├── Taro ├── 工程实践 │ ├── 最佳实践.md │ ├── README.md │ └── 权限校验.md ├── 多端开发 │ └── 跨平台开发.md ├── 语法特性 │ ├── README.md │ └── 组件样式.md ├── TaroUI │ └── README.md ├── README.md └── 开发基础 │ ├── 静态资源.md │ ├── 组件与页面.md │ ├── 快速开始.md │ └── 框架与配置.md ├── UniApp └── README.md ├── Weapp └── README.md ├── 小程序 ├── README.md ├── 转译与运行时.md ├── W3C 小程序标准.md └── 框架语法对比.md └── Remax └── README.md /Taro/工程实践/最佳实践.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /UniApp/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Taro/多端开发/跨平台开发.md: -------------------------------------------------------------------------------- 1 | # 跨平台开发 2 | -------------------------------------------------------------------------------- /Taro/语法特性/README.md: -------------------------------------------------------------------------------- 1 | # 语法特性 2 | -------------------------------------------------------------------------------- /Weapp/README.md: -------------------------------------------------------------------------------- 1 | # 微信小程序开发 2 | -------------------------------------------------------------------------------- /Taro/工程实践/README.md: -------------------------------------------------------------------------------- 1 | # Taro 典型应用设计模式 2 | -------------------------------------------------------------------------------- /小程序/README.md: -------------------------------------------------------------------------------- 1 | # 小程序 2 | 3 | # Links 4 | -------------------------------------------------------------------------------- /Taro/TaroUI/README.md: -------------------------------------------------------------------------------- 1 | # Taro UI 2 | 3 | Taro UI 是一套基于 Taro 框架开发的多端 UI 组件库。 4 | -------------------------------------------------------------------------------- /Remax/README.md: -------------------------------------------------------------------------------- 1 | # Remax 2 | 3 | # Links 4 | 5 | - https://mp.weixin.qq.com/s/Ql3cRQEzdGkQ05V-YvKXeQ 6 | - https://zhuanlan.zhihu.com/p/79788488?spm=ata.13261165.0.0.7d8960a35bcOmI 7 | -------------------------------------------------------------------------------- /小程序/转译与运行时.md: -------------------------------------------------------------------------------- 1 | # 跨端解决方案 2 | 3 | 目前业界跨多端小程序统一开发框架已经有多种方案了,例如美团点评的 mpvue,京东的 Taro,去哪儿的 anu,淘宝的 Rax。 4 | 5 | # Taro 6 | 7 | Taro 遵循 React 语法规范,它采用与 React 一致的组件化思想,组件生命周期与 React 保持一致,同时支持使用 JSX 语法,让代码具有更丰富的表现力,使用 Taro 进行开发可以获得和 React 一致的开发体验。核心部分为编译工具,主要的功能是代码本身的转译以及各个平台 API 层面和自身组件的抹平。 8 | 9 | ![Taro 组成](https://s2.ax1x.com/2019/09/11/nw5Nxe.png) 10 | 11 | 代码转译即借助于编译原理的力量是能够明确做到将 React 转成小程序代码的。将代码按照对应语法规则转换过去后,还远远不够,因为不同端会有自己的原生组件,端能力 API 等等,代码直接转换过去后,可能不能直接执行。为了弥补不同端的差异,他们订制好了一个统一的组件库标准,以及统一的 API 标准,同时还为不同的端编写相应的运行时框架,负责初始化等等操作。 12 | 13 | ![Taro 代码转译](https://s2.ax1x.com/2019/09/11/nw5rIP.png) 14 | 15 | 这一套标准主要以三个部分组成,包括标准运行时框架、标准基础组件库、标准端能力 API,其中运行时框架和 API 对应 @taro/taro,组件库对应 @tarojs/components,通过在不同端实现这些标准,从而达到去差异化的目的。类比于手淘的 Rax,提供很多组件,大部分组件的能力都可以分别映射到 H5 和 weex 两端。 16 | 17 | ![Taro 库标准](https://s2.ax1x.com/2019/09/11/nw5cRS.png) 18 | 19 | 结合组件库和 API 的能力,本地开发源码,经过代码编译成为目标代码,结合各端的运营时就可以达到了在多端适配的目的,真正的一套代码,多端运行。 20 | 21 | ![Taro 多端运行时](https://s2.ax1x.com/2019/09/11/nw5gxg.md.png) 22 | -------------------------------------------------------------------------------- /Taro/README.md: -------------------------------------------------------------------------------- 1 | # Taro 2 | 3 | Taro 是由 京东·凹凸实验室 倾力打造的多端开发解决方案。现如今市面上端的形态多种多样,Web、ReactNative、微信小程序等各种端大行其道,当业务要求同时在不同的端都要求有所表现的时候,针对不同的端去编写多套代码的成本显然非常高,这时候只编写一套代码就能够适配到多端的能力就显得极为需要。使用 Taro,我们可以只书写一套代码,再通过 Taro 的编译工具,将源代码分别编译出可以在不同端(微信小程序、H5、RN 等)运行的代码。 4 | 5 | Taro 遵循 React 语法规范,它采用与 React 一致的组件化思想,组件生命周期与 React 保持一致,同时支持使用 JSX 语法,让代码具有更丰富的表现力,使用 Taro 进行开发可以获得和 React 一致的开发体验。 6 | 7 | ```jsx 8 | import Taro, { Component } from "@tarojs/taro"; 9 | import { View, Button } from "@tarojs/components"; 10 | 11 | export default class Index extends Component { 12 | constructor() { 13 | super(...arguments); 14 | this.state = { 15 | title: "首页", 16 | list: [1, 2, 3] 17 | }; 18 | } 19 | 20 | componentWillMount() {} 21 | 22 | componentDidMount() {} 23 | 24 | componentWillUpdate(nextProps, nextState) {} 25 | 26 | componentDidUpdate(prevProps, prevState) {} 27 | 28 | shouldComponentUpdate(nextProps, nextState) { 29 | return true; 30 | } 31 | 32 | add = e => { 33 | // dosth 34 | }; 35 | 36 | render() { 37 | return ( 38 | 39 | {this.state.title} 40 | 41 | {this.state.list.map(item => { 42 | return {item}; 43 | })} 44 | 47 | 48 | 49 | ); 50 | } 51 | } 52 | ``` 53 | -------------------------------------------------------------------------------- /Taro/开发基础/静态资源.md: -------------------------------------------------------------------------------- 1 | # Taro 静态资源 2 | 3 | 在 Taro 中可以像使用 Webpack 那样自由地引用静态资源,而且不需要安装任何 Loaders。 4 | 5 | # 引用样式文件 6 | 7 | 可以直接通过 ES6 的 `import` 语法来引用样式文件,例如引用 CSS 文件: 8 | 9 | ```jsx 10 | import "./css/path/name.css"; 11 | ``` 12 | 13 | 引用 SCSS 文件 14 | 15 | ```jsx 16 | import "./css/path/name.scss"; 17 | ``` 18 | 19 | # 引用 JS 文件 20 | 21 | 可以直接通过 ES6 的 `import` 语法来引用 JS 文件 22 | 23 | ```jsx 24 | import { functionName } from "./css/path/name.js"; 25 | 26 | import defaultExportName from "./css/path/name.js"; 27 | ``` 28 | 29 | # 引用图片、音频、字体等文件 30 | 31 | 可以直接通过 ES6 的 `import` 语法来引用此类文件,拿到文件引用后直接在 JSX 中进行使用 32 | 33 | ```jsx 34 | // 引用文件 35 | import namedPng from "../https://ngte-superbed.oss-cn-beijing.aliyuncs.com/book/Andrew-Ng-DeepLearning-AI/path/named.png"; 36 | 37 | // 使用 38 | 39 | 40 | ; 41 | ``` 42 | 43 | # 引用 JSON 文件 44 | 45 | 可以直接通过 ES6 的 `import` 语法来引用此类文件,拿到 JSON 文件输出的 JSON 数据 46 | 47 | ```jsx 48 | // 引用 json 文件 49 | /** 50 | * named.json 51 | * { 52 | * x: 1 53 | * } 54 | **/ 55 | import namedJson from "../../json/path/named.json"; 56 | 57 | console.log(namedJson.x); 58 | ``` 59 | 60 | # 小程序样式中引用本地资源 61 | 62 | 在小程序的样式中,默认不能直接引用本地资源,只能通过网络地址、Base64 的方式来进行资源引用,为了方便开发,Taro 提供了直接在样式文件中引用本地资源的方式,其原理是通过 PostCSS 的 postcss-url 插件将样式中本地资源引用转换成 Base64 格式,从而能正常加载。 63 | 64 | Taro 默认会对 `10kb` 大小以下的资源进行转换,如果需要修改配置,可以在 `config/index.js` 中进行修改,配置位于 [`mini.postcss`](https://taro-docs.jd.com/taro/docs/config-detail.html#minipostcss)。具体配置如下 65 | 66 | ```javascript 67 | // 小程序端样式引用本地资源内联 68 | url: { 69 | enable: true, 70 | config: { 71 | limit: 10240 // 设定转换尺寸上限 72 | } 73 | } 74 | ``` 75 | -------------------------------------------------------------------------------- /Taro/开发基础/组件与页面.md: -------------------------------------------------------------------------------- 1 | # 组件与页面 2 | 3 | # 组件的生命周期 4 | 5 | 而且由于入口文件继承自 Component 组件基类,它同样拥有组件生命周期,但因为入口文件的特殊性,他的生命周期并不完整,具体如下。 6 | 7 | ## componentWillMount() 8 | 9 | 在微信/百度/字节跳动/支付宝小程序中这一生命周期方法对应 app 的 onLaunch,监听程序初始化,初始化完成时触发(全局只触发一次)。在此生命周期中通过 `this.$router.params`,可以访问到程序初始化参数。参数格式如下 10 | 11 | | 属性 | 类型 | 说明 | 微信小程序 | 百度小程序 | 字节跳动小程序 | 支付宝小程序 | H5 | RN | 12 | | ------------ | ------ | -------------------------------------------------------------------- | ---------- | ---------- | -------------- | ------------ | --- | --- | 13 | | path | string | 启动小程序的路径 | ✔️ | ✔️ | ✔️ | ✔️ | ✘ | ✘ | 14 | | scene | number | 启动小程序的场景值 | ✔️ | ✔️ | ✔️ | ✘ | ✘ | ✘ | 15 | | query | Object | 启动小程序的 query 参数 | ✔️ | ✔️ | ✔️ | ✔️ | ✘ | ✘ | 16 | | shareTicket | string | shareTicket,详见获取更多转发信息 | ✔️ | ✔️ | ✔️ | ✘ | ✘ | ✘ | 17 | | referrerInfo | Object | 来源信息。从另一个小程序、公众号或 App 进入小程序时返回。否则返回 {} | ✔️ | ✔️ | ✔️ | ✔️ | ✘ | ✘ | 18 | 19 | 其中,场景值 scene,在微信小程序和百度小程序中存在区别,请分别参考 [微信小程序文档](https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/scene.html) 和 [百度小程序文档](http://smartprogram.baidu.com/docs/data/scene/)。来源信息 referrerInfo 的数据结构如下 20 | 21 | | 属性 | 类型 | 说明 | 微信小程序 | 百度小程序 | 字节跳动小程序 | 支付宝小程序 | 22 | | --------------- | ------ | -------------------------------------------------------------------- | ---------- | ---------- | -------------- | ----------------------- | 23 | | appId | string | 来源小程序,或者公众号(微信中) | ✔️ | ✔️ | ✔️ | ✔️ | 24 | | extraData | Object | 来源小程序传过来的数据,微信和百度小程序在 scene=1037 或 1038 时支持 | ✔️ | ✔️ | ✔️ | ✔️ | 25 | | sourceServiceId | string | 来源插件,当处于插件运行模式时可见 | ✘ | ✘ | ✘ | ✔️(基础库版本 1.11.0) | 26 | 27 | ## componentDidMount() 28 | 29 | 在微信/百度/字节跳动/支付宝小程序中这一生命周期方法对应 app 的 `onLaunch`,在 `componentWillMount` 后执行监听程序初始化,初始化完成时触发(全局只触发一次)。在此生命周期中也可以通过 `this.$router.params`,访问到程序初始化参数,与 `componentWillMount` 中一致 30 | -------------------------------------------------------------------------------- /Taro/开发基础/快速开始.md: -------------------------------------------------------------------------------- 1 | # Taro 快速开始 2 | 3 | Taro 项目基于 node,请确保已具备较新的 node 环境(>=8.0.0),推荐使用 node 版本管理工具 nvm 来管理 node,这样不仅可以很方便地切换 node 版本,而且全局安装时候也不用加 sudo 了。首先,你需要使用 npm 或者 yarn 全局安装@tarojs/cli,或者直接使用 npx: 4 | 5 | ```sh 6 | # 使用 npm 安装 CLI 7 | $ npm install -g @tarojs/cli 8 | # OR 使用 yarn 安装 CLI 9 | $ yarn global add @tarojs/cli 10 | # OR 安装了 cnpm,使用 cnpm 安装 CLI 11 | $ cnpm install -g @tarojs/cli 12 | ``` 13 | 14 | 值得一提的是,如果安装过程出现 sass 相关的安装错误,请在安装 mirror-config-china 后重试。 15 | 16 | ```sh 17 | $ npm install -g mirror-config-china 18 | ``` 19 | 20 | # 项目初始化 21 | 22 | 使用命令创建模板项目 23 | 24 | ```bash 25 | $ taro init myApp 26 | ``` 27 | 28 | npm 5.2+ 也可在不全局安装的情况下使用 npx 创建模板项目 29 | 30 | ```bash 31 | $ npx @tarojs/cli init myApp 32 | ``` 33 | 34 | 在创建完项目之后,Taro 会默认开始安装项目所需要的依赖,安装使用的工具按照 yarn>cnpm>npm 顺序进行检测,一般来说,依赖安装会比较顺利,但某些情况下可能会安装失败,这时候你可以在项目目录下自己使用安装命令进行安装: 35 | 36 | ```sh 37 | # 使用 yarn 安装依赖 38 | $ yarn 39 | # OR 使用 cnpm 安装依赖 40 | $ cnpm install 41 | # OR 使用 npm 安装依赖 42 | $ npm install 43 | ``` 44 | 45 | 进入项目目录开始开发,目前已经支持 微信/百度/支付宝/字节跳动/QQ/京东小程序、H5、快应用以及 ReactNative 等端的代码转换,针对不同端的启动以及预览、打包方式并不一致。 46 | 47 | # 运行 48 | 49 | Taro 需要运行不同的命令,将 Taro 代码编译成不同端的代码,然后在对应的开发工具中查看效果。 50 | 51 | ![Taro 运行截图](https://s2.ax1x.com/2020/03/10/8PGZOH.md.png) 52 | 53 | 在使用 Taro 进行多端开发中,请确保 Taro CLI 的版本与你项目的依赖版本一致,否则可能会出现编译错误或者运行时错误。 54 | 55 | ## 微信小程序 56 | 57 | 选择微信小程序模式,需要自行下载并打开微信开发者工具,然后选择项目根目录进行预览。微信小程序编译预览及打包(去掉 --watch 将不会监听文件修改,并会对代码进行压缩打包) 58 | 59 | ```sh 60 | # yarn 61 | 62 | $ yarn dev:weapp 63 | $ yarn build:weapp 64 | 65 | # npm script 66 | 67 | $ npm run dev:weapp 68 | $ npm run build:weapp 69 | 70 | # 仅限全局安装 71 | 72 | $ taro build --type weapp --watch 73 | $ taro build --type weapp 74 | 75 | # npx 用户也可以使用 76 | 77 | $ npx taro build --type weapp --watch 78 | $ npx taro build --type weapp 79 | ``` 80 | 81 | # 路由功能 82 | 83 | 在 Taro 中,路由功能是默认自带的,不需要开发者进行额外的路由配置。我们只需要在入口文件的 config 配置中指定好 pages,然后就可以在代码中通过 Taro 提供的 API 来跳转到目的页面,例如: 84 | 85 | ```js 86 | // 跳转到目的页面,打开新页面 87 | Taro.navigateTo({ 88 | url: "/pages/page/path/name" 89 | }); 90 | 91 | // 跳转到目的页面,在当前页面打开 92 | Taro.redirectTo({ 93 | url: "/pages/page/path/name" 94 | }); 95 | ``` 96 | 97 | ## 路由传参 98 | 99 | 我们可以通过在所有跳转的 `url` 后面添加查询字符串参数进行跳转传参,例如 100 | 101 | ```jsx 102 | // 传入参数 id=2&type=test 103 | Taro.navigateTo({ 104 | url: "/pages/page/path/name?id=2&type=test" 105 | }); 106 | ``` 107 | 108 | 这样的话,在跳转成功的目标页的**生命周期**方法里就能通过 `this.$router.params` 获取到传入的参数,例如上述跳转,在目标页的 `componentWillMount` 生命周期里获取入参 109 | 110 | ```jsx 111 | class C extends Taro.Component { 112 | componentWillMount() { 113 | console.log(this.$router.params); // 输出 { id: 2, type: 'test' } 114 | } 115 | } 116 | ``` 117 | -------------------------------------------------------------------------------- /Taro/工程实践/权限校验.md: -------------------------------------------------------------------------------- 1 | # 权限校验 2 | 3 | ```js 4 | const LIFE_CYCLE_MAP = ["willMount", "didMount", "didShow"]; 5 | 6 | /** 7 | * 8 | * 登录鉴权 9 | * 10 | * @param {string} [lifecycle] 需要等待的鉴权完再执行的生命周期 willMount didMount didShow 11 | * @returns 包装后的Component 12 | * 13 | */ 14 | function withLogin(lifecycle = "willMount") { 15 | // 异常规避提醒 16 | if (LIFE_CYCLE_MAP.indexOf(lifecycle) < 0) { 17 | console.warn( 18 | `传入的生命周期不存在, 鉴权判断异常 ===========> $_{lifecycle}` 19 | ); 20 | return Component => Component; 21 | } 22 | 23 | return function withLoginComponent(Component) { 24 | // 避免H5兼容异常 25 | if (tool.isH5()) { 26 | return Component; 27 | } 28 | 29 | // 这里还可以通过redux来获取本地用户信息,在用户一次登录之后,其他需要鉴权的页面可以用判断跳过流程 30 | // @connect(({ user }) => ({ 31 | // userInfo: user.userInfo, 32 | // })) 33 | return class WithLogin extends Component { 34 | constructor(props) { 35 | super(props); 36 | } 37 | 38 | async componentWillMount() { 39 | if (super.componentWillMount) { 40 | if (lifecycle === LIFE_CYCLE_MAP[0]) { 41 | const res = await this.$_autoLogin(); 42 | if (!res) return; 43 | } 44 | 45 | super.componentWillMount(); 46 | } 47 | } 48 | 49 | async componentDidMount() { 50 | if (super.componentDidMount) { 51 | if (lifecycle === LIFE_CYCLE_MAP[1]) { 52 | const res = await this.$_autoLogin(); 53 | if (!res) return; 54 | } 55 | 56 | super.componentDidMount(); 57 | } 58 | } 59 | 60 | async componentDidShow() { 61 | if (super.componentDidShow) { 62 | if (lifecycle === LIFE_CYCLE_MAP[2]) { 63 | const res = await this.$_autoLogin(); 64 | if (!res) return; 65 | } 66 | 67 | super.componentDidShow(); 68 | } 69 | } 70 | }; 71 | 72 | $_autoLogin = () => { 73 | // ...这里是登录逻辑 74 | }; 75 | }; 76 | } 77 | 78 | export default withLogin; 79 | ``` 80 | 81 | 需要登录鉴权页面的使用方式 pages/xxx/xxx.js: 82 | 83 | ```js 84 | import Taro, { Component } from "@tarojs/taro"; 85 | import { View } from "@tarojs/components"; 86 | import withLogin from "./withLogin"; 87 | 88 | @withLogin() 89 | class Index extends Component { 90 | componentWillMount() { 91 | console.log("Index willMount"); 92 | // 需要带accessToken调用的接口等 93 | } 94 | 95 | componentDidMount() { 96 | console.log("Index didMount"); 97 | } 98 | 99 | render() { 100 | console.log("Index render"); 101 | 102 | return ; 103 | } 104 | } 105 | 106 | export default Index; 107 | ``` 108 | -------------------------------------------------------------------------------- /小程序/W3C 小程序标准.md: -------------------------------------------------------------------------------- 1 | # 小程序框架设计 2 | 3 | # 小程序构造 4 | 5 | 为了获得与原生应用程序相似的用户体验,小程序资源通常打包在一起。下载并安装小程序软件包后,用来显示应用程序页面所需的所有静态页面模板 /CSS/JavaScript 文件都已经在用户的设备上就绪了。在下次更新之前,这些资源始终可用,无需任何额外下载内容。 6 | 7 | 小程序包是压缩格式(例如 zip)存档,包括: 8 | 9 | - 一个配置文档,位于包的根目录下。配置文件应包括:整个小程序的概述;页面描述及其对应路径,用于页面定位和开启。 10 | 11 | - 一个包含 JavaScript 代码的应用级逻辑文件,处理应用级生命周期回调。 12 | 13 | - 一个或多个页面文件,包含页面结构的模板代码、页面样式的 CSS 代码和页面逻辑的 JavaScript 代码。 14 | 15 | - 支持数字签名验证。 16 | 17 | 为了在搜索和执行时定位特定的小程序,小程序必须在平台上具有包名或 ID。还需要一个小程序图标帮助用户识别。 18 | 19 | ## 分离视图层与逻辑层 20 | 21 | 在小程序中,视图层通常与逻辑层分离。 22 | 23 | ![视图与逻辑分离示意](https://s2.ax1x.com/2019/10/06/ucFO9x.png) 24 | 25 | 视图层负责渲染小程序页面,包括 Web 组件和原生组件渲染,可以将其视为混合渲染。例如,Web 组件渲染可以由 WebView 处理,但 WebView 不支持某些 Web 组件渲染,或者是性能受限;小程序还依赖于某些原生组件,例如地图、视频等。逻辑层是用 JS Worker 实现的。Worker 负责小程序的事件处理、API 调用和生命周期管理。 26 | 27 | 扩展的原生功能通常来自宿主原生应用程序或操作系统,这些功能包括支付、文件处理、扫描、电话等。它们通过某些 API 调用。当小程序调用原生 API 时,它会将 API 调用传递给扩展的原生功能,以便通过 JS Bridge 进一步处理,并通过 JS Bridge 从扩展的原生功能获取结果。 28 | 29 | ![调用 API 时小程序的数据流](https://s2.ax1x.com/2019/10/06/uck82V.jpg) 30 | 31 | Worker 为每个 Render 建立连接,传输需要渲染的数据以进一步处理。如果事件由小程序页面中的组件触发,则此页面的 Render 将向 Worker 发送事件以进一步处理。同时,Render 将等待 Worker 发送的数据来重新渲染小程序页面。渲染过程可被视为无状态,并且所有状态都将存储在 Worker 中。 32 | 33 | 视图层和逻辑层分离有很多好处: 34 | 35 | - 方便多个小程序页面之间的数据共享和交互。 36 | - 在小程序的生命周期中具有相同的上下文可以为具备原生应用程序开发背景的开发人员提供熟悉的编码体验。 37 | - Render 和 JS worker 的分离和并行实现可以防止 JS 执行影响或减慢页面渲染,这有助于提高渲染性能。 38 | 39 | # 生命周期 40 | 41 | ## 实例 42 | 43 | 用来发现、打开和访问小程序的入口众多。与多 WebView 的 Web 应用不同,同一个小程序只会创建一个实例,因此小程序以全局一致的方式保持其状态和数据。例如,在一个用户通过二维码入口第一次打开并登录小程序后,当用户从小程序商店等另一个入口返回应用时仍将保持登录状态。 44 | 45 | # 性能与用户体验 46 | 47 | ## 打包体加载 48 | 49 | 使用小程序的构造器,用户只需在首次打开小程序时下载软件包即可,之后无需再次下载小程序中的静态资源(页面 /JavaScript/CSS),这样加载和跳转页面就会更快。此功能可改善用户操作体验并节省网络流量。 50 | 51 | 同时,小程序有一个预下载机制,可以提前下载小程序软件包,或者单独预载第一页,并在下载过程中并行执行流解压,以最大限度地减少小程序启动阶段和耗时,提升初次打开首页的性能表现。 52 | 53 | ## 多重渲染环境 54 | 55 | 小程序在渲染环境之间使用原生页面堆栈管理,页面切换由原生代码驱动。因此,在页面中的手势操作和页面之间的切换可以实现与原生应用完全相同的流畅体验。 56 | 57 | 由于视图层和逻辑层的隔离,视图层可以独立渲染。不受 JavaScript 逻辑代码的阻碍,可以大大提高页面的渲染速度。 58 | 59 | ## 预构建和复用运行时环境 60 | 61 | 小程序的运行时环境通常在启动应用程序之前预先构建,从而缩短了启动时间。预构建的内容包括渲染环境、静态资源、开发人员定义的预取请求和小程序运行时容器。小程序激活后,它将接管预构建的渲染环境,然后我们继续为缓存池预构建新的渲染环境以备下一次使用。渲染环境数量有一个限制,当任何渲染环境关闭或超出数量限制时,最早打开的渲染环境将被销毁。当小程序退出时其运行时将被销毁,而应用程序环境和资源可以复用。 62 | 63 | # 辅助功能 64 | 65 | ## 小程序小部件 66 | 67 | 除了以小程序页面的形式渲染之外,小程序还能以信息片段的形式显示,亦即小程序小部件。在这种形式下,开发人员可以将他们的服务和 / 或内容放到各种宿主场景(称为宿主环境)中,内容可以是助手、搜索页面等。此功能将小程序的服务与场景关联起来,为用户提供更多便利。 68 | 69 | 例如,当用户购买火车票时,智能助手上的小程序小部件立即显示列车的最新状态。用户可以单击这个小部件并跳转到全屏小程序页面以获取更多详细信息。 70 | 71 | ![从主屏幕到小程序的小部件](https://s2.ax1x.com/2019/10/06/ucA2lV.jpg) 72 | 73 | 与小程序页面相同,小部件也由 URI scheme 描述。宿主环境指定小程序包和对应的小部件通过 URI 路径加载,并通过 URI 查询参数将数据传递给小部件。小部件加载后,它将在宿主环境中显示和渲染。来自宿主和小部件的数据以及来自其他小部件的数据会被隔离,以确保安全性和独立性。 74 | 75 | 在许多情况下,小部件可以打开小程序页面以执行更复杂的操作。在这种情况下,小部件通常需要与其对应的小程序共享数据,例如保持一致的登录状态。因此小部件和小程序的数据可以互通。换句话说,小程序小部件和页面具有相同的数据访问权限。 76 | 77 | 小部件的一个目标是让用户忘记传统的应用程序概念,并以服务的形式真正满足用户的需求。因此,除了所有传统的应用程序调用路径之外,小部件还可以在各种场景下由多种方法触发,例如文本关键字、语音分析、图片识别、扫描代码、事件意图等。 78 | 79 | ![小程序小部件交互](https://s2.ax1x.com/2019/10/06/ucEf3t.jpg) 80 | 81 | 小部件的一个目标是让用户忘记传统的应用程序概念,并以服务的形式真正满足用户的需求。因此,除了所有传统的应用程序调用路径之外,小部件还可以在各种场景下由多种方法触发,例如文本关键字、语音分析、图片识别、扫描代码、事件意图等。 82 | -------------------------------------------------------------------------------- /Taro/语法特性/组件样式.md: -------------------------------------------------------------------------------- 1 | # 组件的外部样式和全局样式 2 | 3 | # 样式使用 4 | 5 | 自定义组件对应的样式文件,只对该组件内的节点生效。编写组件样式时,需要注意以下几点: 6 | 7 | - 组件和引用组件的页面不能使用 id 选择器(`#a`)、属性选择器(`[a]`)和标签名选择器,请改用 class 选择器。 8 | - 组件和引用组件的页面中使用后代选择器(`.a .b`)在一些极端情况下会有非预期的表现,如遇,请避免使用。 9 | - 子元素选择器(`.a > .b`)只能用于 `View` 组件与其子节点之间,用于其他组件可能导致非预期的情况。 10 | - 继承样式,如 `font`、`color`,会从组件外(父组件)继承到组件内。但是引用组件时在组件节点上书写的 `className` 无效。 11 | - 除继承样式外,`app.scss` 中的样式、组件所在页面的样式,均对自定义组件无效。 12 | 13 | ```css 14 | #a { 15 | } /* 在组件中不能使用 */ 16 | [a] { 17 | } /* 在组件中不能使用 */ 18 | button { 19 | } /* 在组件中不能使用 */ 20 | .a > .b { 21 | } /* 除非 .a 是 view 组件节点,否则不一定会生效 */ 22 | ``` 23 | 24 | 除此以外,组件可以指定它所在节点的默认样式,使用 :host 选择器。 25 | 26 | ```css 27 | /* 该自定义组件的默认样式 */ 28 | :host { 29 | color: yellow; 30 | } 31 | ``` 32 | 33 | ## 外部样式类 34 | 35 | 如果想传递样式给引用的自定义组件,以下写法(直接传递 `className`)**不可行**: 36 | 37 | ```jsx 38 | /* CustomComp.js */ 39 | export default class CustomComp extends Component { 40 | static defaultProps = { 41 | classname: 'CGDataVis Series', 42 | } 43 | 44 | render () { 45 | return 这段文本的颜色不会由组件外的 class 决定 46 | } 47 | } 48 | /* MyPage.js */ 49 | export default class MyPage extends Component { 50 | render () { 51 | return 52 | } 53 | } 54 | /* MyPage.scss */ 55 | .red-text { 56 | color: red; 57 | } 58 | ``` 59 | 60 | 取而代之的,需要利用 `externalClasses` 定义段定义若干个外部样式类。这个特性从小程序基础库版本 [1.9.90](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html) 开始支持。 61 | 62 | ```jsx 63 | /* CustomComp.js */ 64 | export default class CustomComp extends Component { 65 | static externalClasses = ['my-class'] 66 | 67 | render () { 68 | return 这段文本的颜色由组件外的 class 决定 69 | } 70 | } 71 | /* MyPage.js */ 72 | export default class MyPage extends Component { 73 | render () { 74 | return 75 | } 76 | } 77 | /* MyPage.scss */ 78 | .red-text { 79 | color: red; 80 | } 81 | ``` 82 | 83 | ## 全局样式类 84 | 85 | 使用外部样式类可以让组件使用指定的组件外样式类,如果希望组件外样式类能够完全影响组件内部,可以将组件构造器中的 `options.addGlobalClass` 字段置为 `true`。这个特性从小程序基础库版本 [2.2.3](https://developers.weixin.qq.com/miniprogram/dev/framework/compatibility.html) 开始支持。 86 | 87 | ```jsx 88 | /* CustomComp.js */ 89 | export default class CustomComp extends Component { 90 | static options = { 91 | addGlobalClass: true 92 | } 93 | 94 | render () { 95 | return 这段文本的颜色由组件外的 class 决定 96 | } 97 | } 98 | /* 组件外的样式定义 */ 99 | .red-text { 100 | color: red; 101 | } 102 | ``` 103 | 104 | # 设计稿及尺寸单位 105 | 106 | 在 Taro 中尺寸单位建议使用 px、百分比 %,Taro 默认会对所有单位进行转换。在 Taro 中书写尺寸按照 1:1 的关系来进行书写,即从设计稿上量的长度 100px,那么尺寸书写就是 100px,当转成微信小程序的时候,尺寸将默认转换为 100rpx,当转成 H5 时将默认转换为以 rem 为单位的值。 107 | 108 | 如果你希望部分 px 单位不被转换成 rpx 或者 rem,最简单的做法就是在 px 单位中增加一个大写字母,例如 Px 或者 PX 这样,则会被转换插件忽略。结合过往的开发经验,Taro 默认以 750px 作为换算尺寸标准,如果设计稿不是以 750px 为标准,则需要在项目配置 config/index.js 中进行设置,例如设计稿尺寸是 640px,则需要修改项目配置 config/index.js 中的 designWidth 配置为 640: 109 | 110 | ```js 111 | const config = { 112 | projectName: 'myProject', 113 | date: '2018-4-18', 114 | designWidth: 640, 115 | .... 116 | } 117 | ``` 118 | 119 | 目前 Taro 支持 750、640、828 三种尺寸设计稿,他们的换算规则如下: 120 | 121 | ```js 122 | const deviceRatio = { 123 | 640: 2.34 / 2, 124 | 750: 1, 125 | 828: 1.81 / 2, 126 | }; 127 | ``` 128 | 129 | 建议使用 Taro 时,设计稿以 iPhone 6 `750px` 作为设计尺寸标准。如果你的设计稿是 `375`,不在以上三种之中,那么你需要把 `designWidth` 配置为 `375`,同时在 `deviceRatio` 中添加换算规则如下: 130 | 131 | ```js 132 | { 133 | designWidth: 375, 134 | deviceRatio: { 135 | '375': 1 / 2, 136 | '640': 2.34 / 2, 137 | '750': 1, 138 | '828': 1.81 / 2 139 | } 140 | } 141 | ``` 142 | 143 | 在编译时,Taro 会帮你对样式做尺寸转换操作,但是如果是在 JS 中书写了行内样式,那么编译时就无法做替换了,针对这种情况,Taro 提供了 API Taro.pxTransform 来做运行时的尺寸转换。 144 | 145 | ```js 146 | Taro.pxTransform(10); // 小程序:rpx,H5:rem 147 | ``` 148 | -------------------------------------------------------------------------------- /小程序/框架语法对比.md: -------------------------------------------------------------------------------- 1 | # 小程序使用对比 2 | 3 | # 微信小程序 4 | 5 | ```sh 6 | project.config.json -- 小程序项目配置文件:比如构建方式(es6、postcss等)、appid、项目名称等 7 | app.json -- app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等 8 | /** 文件内容示例 9 | * { 10 | * "pages":[ // 路径 11 | * "pages/index/index", 12 | * "pages/logs/logs" 13 | * ], 14 | * "window":{ 15 | * "backgroundTextStyle":"light", 16 | * "navigationBarBackgroundColor": "#fff", 17 | * "navigationBarTitleText": "WeChat", 18 | * "navigationBarTextStyle":"black" 19 | * }, 20 | * "tabBar": { 21 | * "color": "#999999", 22 | * "selectedColor": "#000000", 23 | * "backgroundColor": "#ffffff", 24 | * "list": [ 25 | * { 26 | * "pagePath": "pages/index/index", 27 | * "text": "信息流", 28 | * "iconPath": "/static/feedUnselected.png", 29 | * "selectedIconPath": "/static/feed.png" 30 | * } 31 | * ] 32 | * } 33 | * } 34 | */ 35 | app.js -- 小程序入口,调用App()函数注册小程序 36 | /** 文件内容示例 37 | * App({ 38 | * onLaunch: function () { } // 监听小程序初始化,全局只触发一次 39 | * }) 40 | */ 41 | app.wxss -- wxss 在css上面扩充了一个自适应单位 rpx,整个屏幕宽度为750rpx;扩展了 @import "common.wxss"; 方法可引入wxss文件 42 | /pages 43 | /index -- 页面目录,这就比较随意了,直接放在pages下面也是阔以的;一个小程序页面包含 js/wxml/wxss/json 四个文件 44 | index.js -- 在其中调用Page()方法初始化页面 45 | /** 文件内容示例 46 | * Page({ 47 | * data: { -- data 是页面第一次渲染使用的初始数据。 48 | * list: [] -- 在wxml中可使用 {{ list }} 来获取 49 | * }, 50 | * onLoad: function (query) { -- 页面加载时触发。一个页面只会调用一次,可通过query对象获取传递过来的参数 51 | * wx.showToast({ 52 | * title: '鹊桥测试', 53 | * icon: 'none', 54 | * duration: 1000 55 | * }); 56 | * }, 57 | * categoryChange: function(event) { 58 | * this.setData({ 59 | * noIndex: event.detail.value 60 | * }); 61 | * } 62 | * }) 63 | */ 64 | index.wxml -- 自定义的一套页面模板 65 | index.wxss 66 | index.json -- 页面配置 67 | /** 文件内容示例 68 | * { 69 | * "navigationBarTitleText": "自定义导航标题", 70 | * "usingComponents": { // 自定义组件 71 | * "Content": "/pages/index/components/content" 72 | * } 73 | * } 74 | 75 | /log 76 | /utils 77 | utils.js 78 | ``` 79 | 80 | ## 自定义组件 81 | 82 | 微信小程序中的自定义组件也需要包含 js、wxml、wxcss【非必须】、json【非必须】四部分,JS 中需要调用 Component()方法进行初始化,例如: 83 | 84 | ```js 85 | // pages/index/components/content.js 86 | Component({ 87 | properties: { -- 对外暴露的参数 88 | content: { -- 每个参数包含type:类型,value:初始值,observer:值变化时响应函数三部分 89 | type: Object, 90 | observer: function (newVal, oldVal, changedPath) { 91 | console.log(newVal); 92 | this.setData({ 93 | content: newVal 94 | }); 95 | } 96 | }, 97 | config: { -- 暴露的参数在wxml中可以通过 {{content}} 来获取 98 | type: Object, 99 | observer: function (newVal, oldVal, changedPath) { 100 | this.setData({ 101 | config: newVal 102 | }); 103 | } 104 | } 105 | }, 106 | data: {} -- 组件内部数据 data, 107 | methods: {} -- 组件中的方法 108 | }) 109 | ``` 110 | 111 | 自小程序基础库版本 2.2.3 版本开始,组件的的生命周期也可以在 lifetimes 字段中定义,且优先级最高。 112 | 113 | - created 组件实例刚刚被创建时执行,此时不能调用 setData 114 | - attached 在组件实例进入页面节点树时执行 115 | - ready 在组件布局完成后执行 116 | - moved 在组件实例被移动到节点树另一个位置时执行 117 | - detached 在组件实例被从页面节点树移除时执行 118 | 119 | 在组件中可通过 pageLifetimes 来定义页面生命周期触发时组件的行为: 120 | 121 | - show 组件所在的页面被展示时执行 122 | - hide 组件所在的页面被隐藏时执行 123 | - resize 组件所在的页面尺寸变化时执行,会传入 size 124 | 125 | 将组件传入自定义组件作为子组件,在 wxml 中提供了 slot 组件来替代传入的子组件(对应 react 中的 this.props.children),如果有多个 slot,则需要在组件的配置文件中 options 字段中开启 multipleSlots 为 true。 126 | 127 | # 淘宝小程序 128 | 129 | ```sh 130 | app.json -- app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等 131 | /** 文件内容示例 132 | * { 133 | * "pages":[ // 路径 134 | * "pages/index/index", 135 | * "pages/logs/logs" 136 | * ], 137 | * "window":{ 138 | * "backgroundTextStyle":"light", 139 | * "navigationBarBackgroundColor": "#fff", 140 | * "navigationBarTitleText": "WeChat", 141 | * "navigationBarTextStyle":"black" 142 | * }, 143 | * "tabBar": { 144 | * "color": "#999999", 145 | * "selectedColor": "#000000", 146 | * "backgroundColor": "#ffffff", 147 | * "list": [ 148 | * { 149 | * "pagePath": "pages/index/index", 150 | * "text": "信息流", 151 | * "iconPath": "/static/feedUnselected.png", 152 | * "selectedIconPath": "/static/feed.png" 153 | * } 154 | * ] 155 | * } 156 | * } 157 | */ 158 | app.js -- 小程序入口,调用App()函数注册小程序 159 | /** 文件内容示例 160 | * App({ 161 | * onLaunch: function () { } // 监听小程序初始化,全局只触发一次 162 | * }) 163 | */ 164 | app.acss -- acss 在css上面扩充了一个自适应单位 rpx,整个屏幕宽度为750rpx; 165 | /pages 166 | /index -- 页面目录,这就比较随意了,直接放在pages下面也是阔以的;一个小程序页面包含 js/axml/acss/json 四个文件 167 | index.js -- 在其中调用Page()方法初始化页面 168 | /** 文件内容示例 169 | * Page({ 170 | * data: { -- data 是页面第一次渲染使用的初始数据。 171 | * list: [] -- 在axml中可使用 {{ list }} 来获取 172 | * }, 173 | * categoryChange: function(event) { 174 | * this.setData({ 175 | * noIndex: event.detail.value 176 | * }); 177 | * } 178 | * }) 179 | */ 180 | index.axml -- 自定义的一套页面模板 181 | index.acss 182 | index.json -- 页面配置 183 | /** 文件内容示例 184 | * { 185 | * "navigationBarTitleText": "自定义导航标题", 186 | * "usingComponents": { // 自定义组件 187 | * "Content": "/pages/index/components/content" 188 | * } 189 | * } 190 | ``` 191 | 192 | # 支付宝小程序 193 | 194 | ```sh 195 | app.json -- app.json 是当前小程序的全局配置,包括了小程序的所有页面路径、界面表现、网络超时时间、底部 tab 等 196 | /** 文件内容示例 197 | * { 198 | * "pages":[ // 路径 199 | * "pages/index/index", 200 | * "pages/logs/logs" 201 | * ], 202 | * "window":{ 203 | * "backgroundTextStyle":"light", 204 | * "navigationBarBackgroundColor": "#fff", 205 | * "navigationBarTitleText": "WeChat", 206 | * "navigationBarTextStyle":"black" 207 | * }, 208 | * "tabBar": { 209 | * "color": "#999999", 210 | * "selectedColor": "#000000", 211 | * "backgroundColor": "#ffffff", 212 | * "list": [ 213 | * { 214 | * "pagePath": "pages/index/index", 215 | * "text": "信息流", 216 | * "iconPath": "/static/feedUnselected.png", 217 | * "selectedIconPath": "/static/feed.png" 218 | * } 219 | * ] 220 | * } 221 | * } 222 | */ 223 | app.js -- 小程序入口,调用App()函数注册小程序 224 | /** 文件内容示例 225 | * App({ 226 | * onLaunch: function () { } // 监听小程序初始化,全局只触发一次 227 | * }) 228 | */ 229 | app.acss -- acss 在css上面扩充了一个自适应单位 rpx,整个屏幕宽度为750rpx; 230 | /pages 231 | /index -- 页面目录,这就比较随意了,直接放在pages下面也是阔以的;一个小程序页面包含 js/axml/acss/json 四个文件 232 | index.js -- 在其中调用Page()方法初始化页面 233 | /** 文件内容示例 234 | * Page({ 235 | * data: { -- data 是页面第一次渲染使用的初始数据。 236 | * list: [] -- 在axml中可使用 {{ list }} 来获取 237 | * }, 238 | * categoryChange: function(event) { 239 | * this.setData({ 240 | * noIndex: event.detail.value 241 | * }); 242 | * } 243 | * }) 244 | */ 245 | index.axml -- 自定义的一套页面模板 246 | index.acss 247 | index.json -- 页面配置 248 | /** 文件内容示例 249 | * { 250 | * "navigationBarTitleText": "自定义导航标题", 251 | * "usingComponents": { // 自定义组件 252 | * "Content": "/pages/index/components/content" 253 | * } 254 | * } 255 | ``` 256 | 257 | ## 自定义组件 258 | 259 | 支付宝小程序中的自定义组件也需要包含 js、axml、acss【非必须】、json【非必须】四部分,JS 中需要调用 Component()方法进行初始化,例如: 260 | 261 | ```js 262 | // pages/index/components/content.js 263 | Component({ 264 | mixins: [{ didMount() {} }], 265 | data: { y: 2 }, 266 | props: { x: 1 }, 267 | didUpdate(prevProps, prevData) {}, 268 | didUnmount() {}, 269 | methods: { 270 | onMyClick(ev) { 271 | my.alert({}); 272 | this.props.onXX({ ...ev, e2: 1 }); 273 | } 274 | } 275 | }); 276 | ``` 277 | 278 | 自定义的组件的生命周期: 279 | 280 | - didMount 首次被渲染,通常在这时请求服务端数据 281 | - didUpdate 组件被更新,一般是组件数据变更 282 | - didUnmount 自定义组件被卸载 283 | -------------------------------------------------------------------------------- /Taro/开发基础/框架与配置.md: -------------------------------------------------------------------------------- 1 | # 框架与配置 2 | 3 | # 框架 4 | 5 | 项目目录结构: 6 | 7 | ```s 8 | ├── dist 编译结果目录 9 | ├── config 配置目录 10 | | ├── dev.js 开发时配置 11 | | ├── index.js 默认配置 12 | | └── prod.js 打包时配置 13 | ├── src 源码目录 14 | | ├── pages 页面文件目录 15 | | | ├── index index 页面目录 16 | | | | ├── index.js index 页面逻辑 17 | | | | └── index.css index 页面样式 18 | | ├── app.css 项目总通用样式 19 | | └── app.js 项目入口文件 20 | └── package.json 21 | ``` 22 | 23 | 一个普通的入口文件示例如下: 24 | 25 | ```js 26 | import Taro, { Component } from "@tarojs/taro"; 27 | import Index from "./pages/index"; 28 | 29 | import "./app.scss"; 30 | 31 | class App extends Component { 32 | // 项目配置 33 | config = { 34 | pages: ["pages/index/index"], 35 | window: { 36 | backgroundTextStyle: "light", 37 | navigationBarBackgroundColor: "#fff", 38 | navigationBarTitleText: "WeChat", 39 | navigationBarTextStyle: "black", 40 | }, 41 | }; 42 | 43 | componentWillMount() {} 44 | 45 | componentDidMount() {} 46 | 47 | componentDidShow() {} 48 | 49 | componentDidHide() {} 50 | 51 | render() { 52 | return ; 53 | } 54 | } 55 | ``` 56 | 57 | 通常入口文件会包含一个 config 配置项,这个配置是整个应用的全局的配置,配置规范基于微信小程序的全局配置进行制定,所有平台进行统一。入口文件中的全局配置,在编译后将生成全局配置文件 app.json。 58 | 59 | # 配置 60 | 61 | ## 配置项列表 62 | 63 | Taro 中全局配置所包含的配置项及各端支持程度如下: 64 | 65 | | 属性 | 类型 | 必填 | 描述 | 微信小程序 | 百度小程序 | 字节跳动小程序 | 支付宝小程序 | H5 | RN | 66 | | ----------------------------------------------------------------------------------------------------------------- | ------------ | ---- | --------------------------------------------------- | ----------------------------- | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | 67 | | [pages](https://taro-docs.jd.com/taro/docs/tutorial.html#pages) | String Array | 是 | 页面路径列表 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | 68 | | [window](https://taro-docs.jd.com/taro/docs/tutorial.html#window) | Object | 否 | 全局的默认窗口表现 | 具体支持程度见下方 | 具体支持程度见下方 | 具体支持程度见下方 | 具体支持程度见下方 | 具体支持程度见下方 | 具体支持程度见下方 | 69 | | [tabBar](https://taro-docs.jd.com/taro/docs/tutorial.html#tabbar) | Object | 否 | 底部 tab 栏的表现 | 具体支持程度见下方 | 具体支持程度见下方 | 具体支持程度见下方 | 具体支持程度见下方 | 具体支持程度见下方 | 具体支持程度见下方 | 70 | | [networkTimeout](https://taro-docs.jd.com/taro/docs/tutorial.html#networktimeout) | Object | 否 | 网络超时时间 | ✔️ | ✘ | ✘ | ✘ | ✘ | ✘ | 71 | | [debug](https://taro-docs.jd.com/taro/docs/tutorial.html#debug) | Boolean | 否 | 是否开启 debug 模式,默认关闭 | ✔️ | ✘ | ✔️ | ✘ | ✘ | ✘ | 72 | | [functionalPages](https://taro-docs.jd.com/taro/docs/tutorial.html#functionalpages) | Boolean | 否 | 是否启用插件功能页,默认关闭 | ✔️(基础库 2.1.0 以上) | ✘ | ✘ | ✘ | ✘ | ✘ | 73 | | [subPackages](https://taro-docs.jd.com/taro/docs/tutorial.html#subpackages) | Object Array | 否 | 分包结构配置 | ✔️(基础库 1.7.3 以上) | ✔️ | ✘ | ✘ | ✔️ | ✔️ | 74 | | [workers](https://taro-docs.jd.com/taro/docs/tutorial.html#workers) | String | 否 | Worker 代码放置的目录 | ✔️(基础库 1.9.90 以上) | ✘ | ✘ | ✘ | ✘ | ✘ | 75 | | [requiredBackgroundModes](https://taro-docs.jd.com/taro/docs/tutorial.html#requiredbackgroundmodes) | String Array | 否 | 需要在后台使用的能力,如音乐播放 | ✔️ | ✘ | ✘ | ✘ | ✘ | ✘ | 76 | | [plugins](https://taro-docs.jd.com/taro/docs/tutorial.html#plugins) | Object | 否 | 使用到的插件 | ✔️(基础库 1.9.6 以上) | ✘ | ✘ | ✘ | ✘ | ✘ | 77 | | [preloadRule](https://taro-docs.jd.com/taro/docs/tutorial.html#preloadrule) | Object | 否 | 分包预下载规则 | ✔️(基础库 2.3.0 以上) | ✔️ | ✘ | ✘ | ✘ | ✘ | 78 | | [resizable](https://taro-docs.jd.com/taro/docs/tutorial.html#resizable) | Boolean | 否 | iPad 小程序是否支持屏幕旋转,默认关闭 | ✔️(基础库 2.3.0 以上) | ✘ | ✘ | ✘ | ✘ | ✘ | 79 | | [navigateToMiniProgramAppIdList](https://taro-docs.jd.com/taro/docs/tutorial.html#navigatetominiprogramappidlist) | String Array | 否 | 需要跳转的小程序列表,详见 wx.navigateToMiniProgram | ✔️(基础库 2.4.0 以上) | ✘ | ✘ | ✘ | ✘ | ✘ | 80 | | [usingComponents](https://taro-docs.jd.com/taro/docs/tutorial.html#usingcomponents) | Object | 否 | 全局自定义组件配置 | ✔️(开发者工具 1.02.1810190) | ✘ | ✘ | ✘ | ✘ | ✘ | 81 | | [permission](https://taro-docs.jd.com/taro/docs/tutorial.html#permission) | Object | 否 | 小程序接口权限相关设置 | ✔️ 微信客户端 7.0.0 | ✘ | ✘ | ✘ | ✘ | ✘ | 82 | 83 | ## pages 84 | 85 | 用于指定小程序由哪些页面组成,每一项都对应一个页面的 路径 + 文件名 信息。文件名不需要写文件后缀,框架会自动去寻找对应位置的文件进行处理。数组的第一项代表小程序的初始页面(首页)。小程序中新增/减少页面,都需要对 pages 数组进行修改。如开发目录为: 86 | 87 | ```s 88 | ├── app.js 89 | ├── app.json 90 | ├── app.wxss 91 | ├── pages 92 | │ │── index 93 | │ │ ├── index.wxml 94 | │ │ ├── index.js 95 | │ │ ├── index.json 96 | │ │ └── index.wxss 97 | │ └── logs 98 | │ ├── logs.wxml 99 | │ └── logs.js 100 | └── utils 101 | ``` 102 | 103 | 则需要在入口文件配置中写 104 | 105 | ```jsx 106 | class App extends Component { 107 | // 项目配置 108 | config = { 109 | pages: [ 110 | 'pages/index/index', 111 | 'pages/logs/logs' 112 | ] 113 | } 114 | ... 115 | } 116 | ``` 117 | 118 | ## window 119 | 120 | 用于设置小程序的状态栏、导航条、标题、窗口背景色,其配置项如下。 121 | 122 | | 属性 | 类型 | 默认值 | 描述 | 123 | | ---------------------------- | -------------------------- | -------- | ------------------------------------------------------------------------------------- | 124 | | navigationBarBackgroundColor | HexColor(十六进制颜色值) | #000000 | 导航栏背景颜色,如 #000000 | 125 | | navigationBarTextStyle | String | white | 导航栏标题颜色,仅支持 black / white | 126 | | navigationBarTitleText | String | | 导航栏标题文字内容 | 127 | | navigationStyle | String | default | 导航栏样式,仅支持以下值:default 默认样式;custom 自定义导航栏,只保留右上角胶囊按钮 | 128 | | backgroundColor | String | | 窗口的背景色 | 129 | | backgroundTextStyle | String | dark | 下拉 loading 的样式,仅支持 dark / light | 130 | | backgroundColorTop | String | #ffffff | 顶部窗口的背景色,仅 iOS 支持 | 131 | | backgroundColorBottom | String | #ffffff | 底部窗口的背景色,仅 iOS 支持 | 132 | | enablePullDownRefresh | boolean | false | 是否开启当前页面的下拉刷新。 | 133 | | onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位为 px | 134 | | pageOrientation | String | portrait | 屏幕旋转设置,支持 auto / portrait / landscape 详见 响应显示区域变化 | 135 | 136 | 各端支持程度如下: 137 | 138 | | 属性 | 微信小程序 | 百度小程序 | 字节跳动小程序 | 支付宝小程序 | H5 | RN | 139 | | ---------------------------- | ---------------------------------- | -------------------------- | -------------- | ------------ | --- | --- | 140 | | navigationBarBackgroundColor | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | 141 | | navigationBarTextStyle | ✔️ | ✔️ | ✔️ | ✘ | ✔️ | ✔️ | 142 | | navigationBarTitleText | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | 143 | | navigationStyle | ✔️(微信客户端 6.6.0) | ✔️(百度 App 版本 11.1.0) | ✔️ | ✘ | ✘ | ✘ | 144 | | backgroundColor | ✔️ | ✔️ | ✔️ | ✘ | ✘ | ✔️ | 145 | | backgroundTextStyle | ✔️ | ✔️ | ✔️ | ✘ | ✘ | ✘ | 146 | | backgroundColorTop | ✔️(微信客户端 6.5.16) | ✘ | ✔️ | ✘ | ✘ | ✘ | 147 | | backgroundColorBottom | ✔️(微信客户端 6.5.16) | ✘ | ✔️ | ✘ | ✘ | ✘ | 148 | | enablePullDownRefresh | ✔️ | ✔️ | ✔️ | ✔️ | ✘ | ✘ | 149 | | onReachBottomDistance | ✔️ | ✔️ | ✔️ | ✘ | ✘ | ✘ | 150 | | pageOrientation | ✔️2.4.0 (auto) / 2.5.0 (landscape) | ✘ | ✘ | ✘ | ✘ | ✘ | 151 | 152 | 配置示例如下: 153 | 154 | ```jsx 155 | class App extends Component { 156 | // 项目配置 157 | config = { 158 | pages: [ 159 | 'pages/index/index', 160 | 'pages/logs/logs' 161 | ], 162 | window: { 163 | navigationBarBackgroundColor: '#ffffff', 164 | navigationBarTextStyle: 'black', 165 | navigationBarTitleText: '微信接口功能演示', 166 | backgroundColor: '#eeeeee', 167 | backgroundTextStyle: 'light' 168 | } 169 | } 170 | ... 171 | } 172 | ``` 173 | 174 | ## tabBar 175 | 176 | 如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。 177 | 178 | 其配置项如下 179 | 180 | | 属性 | 类型 | 必填 | 默认值 | 描述 | 181 | | --------------- | -------------------------- | ---- | ------ | -------------------------------------------------------- | 182 | | color | HexColor(十六进制颜色值) | 是 | | tab 上的文字默认颜色,仅支持十六进制颜色 | 183 | | selectedColor | HexColor(十六进制颜色值) | 是 | | tab 上的文字选中时的颜色,仅支持十六进制颜色 | 184 | | backgroundColor | HexColor(十六进制颜色值) | 是 | | tab 的背景色,仅支持十六进制颜色 | 185 | | borderStyle | String | 是 | black | tabbar 上边框的颜色,仅支持 black / white | 186 | | list | Array | 是 | | tab 的列表,详见 list 属性说明,最少 2 个、最多 5 个 tab | 187 | | position | String | 否 | bottom | tabBar 的位置,仅支持 bottom / top | 188 | | custom | Boolean | 否 | false | 自定义 tabBar | 189 | 190 | 各端支持程度如下 191 | 192 | | 属性 | 微信小程序 | 百度小程序 | 字节跳动小程序 | 支付宝小程序 | H5 | RN | 193 | | --------------- | ----------------------- | ---------- | -------------- | ------------ | --- | --- | 194 | | color | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | 195 | | selectedColor | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | 196 | | backgroundColor | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | 197 | | borderStyle | ✔️ | ✔️ | ✔️ | ✘ | ✔️ | ✔️ | 198 | | list | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | 199 | | position | ✔️ | ✘ | ✔️ | ✘ | ✘ | ✘ | 200 | | custom | ✔️(基础库 2.5.0 以上) | ✘ | ✘ | ✘ | ✘ | ✘ | 201 | 202 | 其中 list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。tab 按数组的顺序排序,每个项都是一个对象,其属性值如下: 203 | 204 | | 属性 | 类型 | 必填 | 描述 | 205 | | ---------------- | ------ | ---- | --------------------------------------------------------------------------------------------------------------------- | 206 | | pagePath | String | 是 | 页面路径,必须在 pages 中先定义 | 207 | | text | String | 是 | tab 上按钮文字 | 208 | | iconPath | String | 否 | 图片路径,icon 大小限制为 40kb,建议尺寸为 81px \* 81px,不支持网络图片。当 position 为 top 时,不显示 icon。 | 209 | | selectedIconPath | String | 否 | 选中时的图片路径,icon 大小限制为 40kb,建议尺寸为 81px \* 81px,不支持网络图片。当 position 为 top 时,不显示 icon。 | 210 | 211 | ## networkTimeout 212 | 213 | 各类网络请求的超时时间,单位均为毫秒。 214 | 215 | | 属性 | 类型 | 必填 | 默认值 | 描述 | 216 | | ------------- | ------ | ---- | ------ | ------------------------------------------------------------------------------------------------------- | 217 | | request | Number | 否 | 60000 | [Taro.request](https://taro-docs.jd.com/taro/docs/native-api.md#发起请求) 的超时时间,单位:毫秒 | 218 | | connectSocket | Number | 否 | 60000 | [Taro.connectSocket](https://taro-docs.jd.com/taro/docs/native-api.md#websocket) 的超时时间,单位:毫秒 | 219 | | uploadFile | Number | 否 | 60000 | [Taro.uploadFile](https://taro-docs.jd.com/taro/docs/native-api.md#上传-下载) 的超时时间,单位:毫秒 | 220 | | downloadFile | Number | 否 | 60000 | [Taro.downloadFile](https://taro-docs.jd.com/taro/docs/native-api.md#上传-下载) 的超时时间,单位:毫秒 | 221 | --------------------------------------------------------------------------------