文章目录
1. 使用npm包1.1 小程序对 npm 的支持与限制1.2 Vant Weapp 组件库1.2.1 安装 Vant 组件库1.2.2 使用 Vant 组件1.2.3 定制全局主题样式 1.3 API Promise化1.3.1 实现 API Promise 化1.3.2 调用 Promise 化之后的异步 API 2. 全局数据共享2.1 小程序中的全局数据共享方案2.2 MobX2.2.1 安装 MobX 相关的包2.2.2 创建 MobX 的 Store 实例2.2.3 将 Store 中的成员绑定到页面中2.2.4 在页面上使用 Store 中的成员2.2.5 将 Store 中的成员绑定到组件中2.2.6 在组件中使用 Store 中的成员 3. 分包3.1 基础概念3.1.1 分包前项目的构成3.1.2 分包后项目的构成3.1.3 分包的加载规则3.1.4 分包的体积限制 3.2 使用分包3.2.1 配制方法3.2.2 打包原则3.2.3 引用原则 3.3 独立分包3.3.1 独立分包的应用场景3.3.2 独立分包的配置方法3.3.3 引用原则 3.4 分包预下载3.4.1 配置分包的预下载3.4.2 分包预下载的限制1. 使用npm包
1.1 小程序对 npm 的支持与限制
目前,小程序中已经支持使用 npm 安装第三方包,从而来提高小程序的开发效率。但是,在小程序中使用 npm 包有如下 3 个限制:
① 不支持依赖于 Node.js 内置库的包② 不支持依赖于浏览器内置对象的包③ 不支持依赖于 C++ 插件的包
总结:虽然 npm 上的包有千千万,但是能供小程序使用的包却 “为数不多” 。
1.2 Vant Weapp 组件库
Vant Weapp 是有赞前端团队开源的一套小程序 UI 组件库,助力开发者快速搭建小程序应用。它所使用的是 MIT 开源许可协议,对商业使用比较友好。官方文档地址: https://youzan.github.io/vant-weapp1.2.1 安装 Vant 组件库
在小程序项目中,安装 Vant 组件库主要分为如下 3 步:
① 通过 npm 安装(建议指定版本为@1.3.3)② 构建 npm 包③ 修改 app.json
官方快速上手教程:https://youzan.github.io/vant-weapp/#/quickstart#an-zhuang
1.2.2 使用 Vant 组件
安装完 Vant 组件库之后,可以在app.json
的usingComponents
节点中引入需要的组件,即可在 wxml 中直接使用组件。示例代码如下:
// app.json"usingComponents": {"van-button": "@vant/weapp/button/index"}// 某页面 .wxml 结构<van-button type="danger">危险按钮</van-button>
1.2.3 定制全局主题样式
前提知识:需要知道CSS 变量的基本用法,请参考 MDN 文档:CSS变量
在app.wxss
中,写入 CSS 变量,即可对全局生效:
/* app.wxss */;/* 这个page 是微信app根元素 */page {/* 定制警告按钮的背景色和边框颜色 */--button-danger-background-color: red;--button-danger-border-color: #000;}
所有可用的颜色变量,请参考 Vant 官方提供的配置文件:地址
1.3 API Promise化
默认情况下,小程序官方提供的异步 API 都是基于回调函数实现的(如:网络请求的 API) ,容易造成回调地狱的问题,代码的可读性、维护性差!API Promise化,指的是通过额外的配置,将官方提供的、基于回调函数的异步 API,升级改造为基于 Promise 的异步 API,从而提高代码的可读性、维护性,避免回调地狱的问题。1.3.1 实现 API Promise 化
在小程序中,实现 API Promise 化主要依赖于miniprogram-api-promise
这个第三方的 npm 包。它的安装和使用步骤如下:
# 可在微信为开发者工具的资源管理器区域右键,点击 在外部窗口中打开npm install --save miniprogram-api-promise
// 在小程序入口文件中(app.js), 只需调用一次 promisifyAll() 方法// 即可实现异步 API 的 Promise 化import {promisifyAll} from 'miniprogram-api-promise';const wxp = wx.p = {}// promisify all wx's apipromisifyAll(wx, wxp)
1.3.2 调用 Promise 化之后的异步 API
// 页面的 .wxml 结构<van-button type="default" bindtap="getInfo">默认按钮</van-button>// 在页面的 .js 文件中 , 定义响应的 tap事件处理函数async getInfo() {const res = await wx.p.request({url: '/api/get',method: 'GET',data: {name: 'zs'}});console.log(res);}
2. 全局数据共享
全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题。开发中常用的全局数据共享方案有:Vuex(在vue.js使用)、Redux(在react中使用)、MobX 等。2.1 小程序中的全局数据共享方案
在小程序中,可使用mobx-miniprogram
配合mobx-miniprogram-bindings
实现全局数据共享。其中:
mobx-miniprogram 用来创建 Store 实例对象mobx-miniprogram-bindings 用来把 Store 中的共享数据或方法,绑定到组件或页面中使用
2.2 MobX
2.2.1 安装 MobX 相关的包
在项目中运行如下的命令,安装 MobX 相关的包:
npm install --save mobx-miniprogram mobx-miniprogram-bindings
注意:MobX 相关的包安装完毕之后,重新构建 npm(在开发者工具的左上角的工具栏)
2.2.2 创建 MobX 的 Store 实例
在项目根目录新建store -> store.js
import {observable,action } from 'mobx-miniprogram'export const store = observable({// 数据字段numA: 1,numB: 2,// 计算属性get sun() {return this.numA + this.numB},// actions 方法, 用来修改 store 中的数据updateNum1: action(function (step) {this.numA += step;}),updateNum2: action(function (step) {this.numB += step;})})
2.2.3 将 Store 中的成员绑定到页面中
// 某页面的 .js 文件import {createStoreBindings} from 'mobx-miniprogram-bindings'import {store} from "../../store/store";Page({onLoad(options) {this.storeBindings = createStoreBindings(this,{store,fields:['numA','numB','sum'],actions:['updateNum1','updateNum2']})},onUnload() {this.storeBindings.destroyStoreBindings();},})
2.2.4 在页面上使用 Store 中的成员
// 某页面的 .wxml 结构<view>{{numA}} + {{numB}} = {{sum}}</view><button bindtap="btnHandle" data-step="{{2}}">步长2</button><button bindtap="btnHandle" data-step="{{-2}}">步长-2</button>// 按钮 的 事件处理函数btnHandle(e) {this.updateNum1(e.target.dataset.step);}
2.2.5 将 Store 中的成员绑定到组件中
import {storeBindingsBehavior } from 'mobx-miniprogram-bindings';import {store } from '../../store/store'Component({behaviors: [storeBindingsBehavior], // 通过 storeBindingsBehavior 来实现自动绑定storeBindings: {store, // 指定要绑定的storefields: {// 指定要绑定的字段数据numA: () => store.numA, // 绑定数据的第一种方式numB: (store) => store.numB, // 绑定数据的第二种方式sum: 'sum', // 绑定数据的第三种方式},actions: {// 指定要绑定的方法updateNum2: 'updateNum2',updateNum1: 'updateNum1'}}})
2.2.6 在组件中使用 Store 中的成员
// 组件的 .wxml 结构<view>{{numA}} + {{numB}} = {{sum}}</view><button bindtap="btnHandle" data-step="{{2}}">步长2</button><button bindtap="btnHandle" data-step="{{-2}}">步长-2</button>// 组件的方法列表methods: {btnHandle(e) {this.updateNum1(e.target.dataset.step);},}
3. 分包
3.1 基础概念
分包概念:把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。分包好处: 可以优化小程序首次启动的下载时间在多团队共同开发时可以更好的解耦协作
3.1.1 分包前项目的构成
分包前,小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的下载时间。
3.1.2 分包后项目的构成
分包后,小程序项目由1 个主包 + 多个分包组成:
主包:一般只包含项目的启动页面或TabBar 页面、以及所有分包都需要用到的一些公共资源分包:只包含和当前分包有关的页面和私有资源
3.1.3 分包的加载规则
① 在小程序启动时,默认会下载主包并启动主包内页面
tabBar 页面需要放到主包中
② 当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示
非 tabBar 页面可以按照功能的不同,划分为不同的分包之后,进行按需下载
3.1.4 分包的体积限制
目前,小程序分包的大小有以下两个限制:
整个小程序所有分包大小不超过16M(主包 + 所有分包)单个分包/主包大小不能超过2M
3.2 使用分包
3.2.1 配制方法
假设支持分包的小程序目录结构如下:
├── app.js├── app.json├── app.wxss├── packageA│ └── pages│ ├── cat│ └── dog├── packageB│ └── pages│ ├── apple│ └── banana├── pages│ ├── index│ └── logs└── utils
开发者通过在app.json
的subpackages
字段声明项目分包结构:
{"pages":[ // 主包的所有页面"pages/index","pages/logs"],"subpackages": [ // 通过此节点,声明分包的结构{"root": "packageA", // 第一个分包的根目录"pages": [ // 当前分包下, 所有页面的相对存放路径"pages/cat","pages/dog"]}, {"root": "packageB",// 第二个分包的根目录"name": "pack2", // 分包的别名"pages": [ // 当前分包下, 所有页面的相对存放路径"pages/apple","pages/banana"]}]}
3.2.2 打包原则
① 小程序会按subpackages
的配置进行分包,subpackages 之外的目录将被打包到主包中② 主包也可以有自己的 pages(即最外层的 pages 字段)③ tabBar 页面必须在主包内④ 分包之间不能互相嵌套3.2.3 引用原则
① 主包无法引用分包内的私有资源② 分包之间不能相互引用私有资源③ 分包可以引用主包内的公共资源3.3 独立分包
独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其他分包而单独运行。
独立分包和普通分包的区别:是否依赖于主包才能运行
普通分包必须依赖于主包才能运行独立分包可以在不下载主包的情况下,独立运行
3.3.1 独立分包的应用场景
开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中原因如下:
当小程序从普通的分包页面启动时,需要首先下载主包而独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度
注意:一个小程序中可以有多个独立分包。
3.3.2 独立分包的配置方法
假设小程序目录结构如下:
├── app.js├── app.json├── app.wxss├── moduleA // 普通分包│ └── pages│ ├── rabbit│ └── squirrel├── moduleB // 独立分包│ └── pages│ ├── pear│ └── pineapple├── pages // 主包的所有页面│ ├── index│ └── logs└── utils
开发者通过在app.json
的subpackages
字段中对应的分包配置项中定义independent
字段声明对应分包为独立分包。
{"pages": ["pages/index","pages/logs"],"subpackages": [{"root": "moduleA","pages": ["pages/rabbit","pages/squirrel"]}, {"root": "moduleB","pages": ["pages/pear","pages/pineapple"],"independent": true}]}
3.3.3 引用原则
独立分包和普通分包以及主包之间,是相互隔绝的,不能相互引用彼此的资源!例如:
① 主包无法引用独立分包内的私有资源② 独立分包之间,不能相互引用私有资源③ 独立分包和普通分包之间,不能相互引用私有资源④ 特别注意:独立分包中不能引用主包内的公共资源
3.4 分包预下载
分包预下载指的是:在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面时的启动速度。
3.4.1 配置分包的预下载
预下载分包的行为,会在进入指定的页面时触发。在app.json
中,使用preloadRule
节点定义分包的预下载规则,示例代码如下:
"preloadRule": {// 分包预下载的规则"pages/index": {// 触发分包预下载的页面路径// network 表示在 指定的网络模式下进行预下载// all(不限网络), wifi(仅wifi模式下可预下载)"network": "all",// packages 表示进入页面后,预下载哪些分包// 可以通过 root 或者 name 指定预下载哪些分包"packages": ["pagA"]}}
3.4.2 分包预下载的限制
同一个分包中的页面享有共同的预下载大小限额 2M,例如: