1、使用npm包
1. 小程序中使用npm包有以下限制
- 不支持依赖于Node.js内置库的包
- 不支持依赖于浏览器内置对象的包
- 不支持依赖于C++插件的包
2. Vant Weapp
- 什么是Vant Weapp
Vant Weapp是一套小程序UI组件库,主力于开发者快速搭建小程序应用。它所使用的是MIT开源许可协议,对商业使用比较友好。
https://youzan.github.io/vant-weapp
- 安装Vant组件库,主要分为如下3步(npm init -y,自动初始化包管理配置文件):
- 通过npm安装(建议指定版本为@1.3.3)
- 构建npm包
- 修改app.json
-
使用Vant组件
在app.json的usingComponents节点中引入需要的组件,即可在wxml中直接使用组件。实例如下:// app.json 文件
"usingComponents": {
"van-button": "@vant/weapp/button/index"
}
// wxml文件
<van-button type="info">按钮</van-button> -
定制全局主题样式
Vant Weapp使用CSS变量来实现定制主题。
在app.wxss中,写入CSS变量,即可对全局生效(每个子页面的根节点都是page):// app.wxss
page {
--button-danger-background-color: #C00000;
--button-danger-border-color: #D60000;
}
3. API Promise化
-
基于回调函数的异步API的缺点
默认情况下,小程序官方提供的异步API都是基于回调函数实现的,例如:网络请求的API需要按照如下方式调用:wx.request({
method: '',
url: '',
data: {},
success: ()=>{},
fail: ()=>{},
complete: ()=>{}
})
缺点:容易造成回调地狱的问题,代码的可读性、维护性查。
- 什么是API Promise化
API Promise化,就是通过额外的配置,将官方提供的、基于回调函数的异步API,升级改造为基于Promise的异步API,从而提高代码的可读性、维护性,避免回调地狱的问题。
- 实现API Promise化
在小程序中,实现API Promise主要依赖于miniprogram-api-promise这个第三方的npm包。它的包装和使用步骤如下:
npm i --save miniprogram-api-promise@1.0.4
import {promisifyAll} from 'miniprogram-api-promise'
const wxp = wx.p = {}
promisifyAll(wx, wxp)
在小程序的app.js文件,只需调用一次 promisifyAll 方法,即可实现异步API的Promise化。
-
调用Promise之后的异步API
<van-button type="danger" bindtap="getInfo">按钮</van-button>
async getInfo() {
const {data:res} = await wx.p.request({
method: 'GET',
url: '',
data: {name: 'zs', age: 18}
});
console.log(res);
}
2、全局数据共享
1. 什么是全局数据共享
全局数据共享又叫做状态管理,是为了解决组件之间数据共享的问题。
常用的数据共享方案有:Vuex、Redux、Mobx
2. 小程序中的全局数据共享方案
在小程序中,可使用mobx-miniprogram配合mobx-miniprogram-bindings实现全局数据共享。
- mobx-miniprogram用来创建Store实例对象。
- mobx-miniprogram-bindings用来把Store中的共享数据或方法,绑定到组件或页面中使用。
3. 使用Mobx
-
安装Mobx相关的包:
npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1
-
创建Store实例: 创建Store文件夹,store文件
import {observable, action} from 'mobx-miniprogram'
export const store = observable({
// 数据字段
numA: 1,
numB: 2,
// 计算属性: get + 函数名
get sum() {
return this.numA + this.numB;
},// actions 方法,用来修改store中的数据
updateNum1: action(function (step) {
this.numA += step;
}),
updateNum2: action(function (step) {
this.numB += step;
}),
}) -
将Store中的成员绑定到页面中:页面的js文件中
// 页面的.js文件
import {createStoreBindings} from 'mobx-miniprogram-binding'
import {store} from '../../Store/store'
Page({
onLoad: function() {
this.storeBindings = createStoreBindings(this, {
store,
fields: ['numA', 'numB', 'sum'],
actions: ['updateNum1', 'updateNum2']
})
},
onUnload: function() {
this.storeBindings.destroyStoreBindings()
}
}) -
在页面上使用Store中的成员:页面的wxml和JS文件
<view>{{numA}} + {{numB}} = {{sum}}</view>
<van-button type="primary" bindtap="btnHandler1" data-step="{{1}}">numA + 1</van-button>
<van-button type="danger" bindtap="btnHandler1" data-step="{{-1}}">numA - 1</van-button>btnHandler1(e) {
this.updateNum1(e.target.dataset.step);
},
可以为组件提供data-*自定义属性传参,其中*代表的是参数的名字。
<button bindtap="btnHandler" data-info="{``{2}}">事件传参</button>
info 会被解析为 参数的名字
数值 2 会被解析为 参数的值
在事件处理函数中,通过event.target.dataset.参数名获取到具体参数的值。
-
将Store的成员绑定到组件中
import {storeBindingsBehavior} from 'mobx-miniprogram-bindings'
import {store} from '../../Store/store'
Component({
behaviors: [storeBindingsBehavior], // 通过storeBindingsBehavior来实现自动绑定storeBindings: {
store, // 指定要绑定的store
fields: { // 指定要绑定的字段数据
numA:()=>store.numA, // 绑定字段的第1种方式
numB:(store)=>store.numB, // 绑定字段的第2种方式
sum: 'sum' // 绑定字段的第3种方式
},
actions: { // 指定要绑定的方法
updateNum2: 'updateNum2'
}
}
}) -
在组件中使用Store的成员
// 组件的wxml结构
<view>{{numA}} + {{numB}} = {{sum}}</view>
<van-button type="primary" bindtap="btnHandler2" data-step="{{1}}">numB + 1</van-button>
<van-button type="danger" bindtap="btnHandler2" data-step="{{-1}}">numB - 1</van-button>btnHandler2(e) {
this.updateNum2(e.target.dataset.step);
},
3、分包
1. 什么是分包
分包指的是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。
2. 分包的好处
- 可以优化小程序首次启动的下载时间
- 在多团队共同开发时可以更好的解耦协作
3. 分包前项目的构成
分包前,小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的下载时间。
4. 分包后项目的构成
分包后,小程序项目由1个主包+多个分包组成:
- 主包:一般只包含项目的启动页面或TabBar页面、以及所有分包都需要用到的一些公共资源
- 分包:只包含和当前分包有关的页面和私有资源
5. 分包的加载规则
- 在小程序启动时,默认会下载主包并启动主包内页面
- tabBar页面需要放到主包中
- 当用户今天分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示
- 非tabBar页面可以按照功能的不同,划分为不同的分包之后,进行按需下载
6. 分包的体积限制
- 整个小程序所有分包大小不能超过16M
- 单个分包/主包大小不能超过2M
7. 使用分包
-
创建
{
"pages":[
"pages/home/home"
],
"subPackages": [
{
"root": "packageA",
"name": "p1",
"pages": [
"pages/cat/cat",
"pages/dog/dog"
]
},
{
"root": "packageB",
"name": "p2",
"independent": true,
"pages": [
"pages/apple/apple",
"pages/pear/pear"
]
}
],
"tabBar": {
"list": [
{
"pagePath": "pages/home/home",
"text": "首页",
"iconPath": "/images/tabs/home.png",
"selectedIconPath": "/images/tabs/home-active.png"
}
]
},
"usingComponents": {
"van-button": "@vant/weapp/button/index",
"my-numbers": "./components/numbers/numbers"
}
} -
打包原则
- 小程序会按subpackages的配置进行分包,subpackages之外的目录将被打包到主包中
- 主包也可以有自己的pages(即最外层的pages字段)
- tabBar页面必须在主包内
- 分包之间不能相互嵌套
- 引用原则
- 主包无法引用分包内的私有资源
- 分包之间不能相互引用私有资源
- 分包可以引用主包内的公告资源
8. 独立分包
- 什么是独立分包
独立分包本质上也是分包,只不过比较特殊,可以独立于主包和其他分包而单独运行。 - 独立分包和普通分包的区别
最主要的区别:是否依赖于主包才能运行
- 普通分包必须依赖于主包才能运行
- 独立分包可以在不下载主包的情况下,独立运行
- 独立分包的应用场景
可以按需,将某些具有一定功能独立性的页面配置到独立分包中。原因如下:
- 当小程序从普通的分包页面启动时,需要首先下载主包
- 独立分包不依赖主包即可运行,可以很大程度上提示分包页面的启动速度
一个小程序中可以有多个独立分包。
-
配置独立分包
-
引用原则
独立分包和普通分包以及主包之间,是相互隔绝的,不能相互引用彼此的资源。
- 主包无法引用独立分包内的私有资源
- 独立分包之间,不能相互引用私有资源
- 独立分包和普通分包之间,不能相互引用私有资源
- 独立分包内不能引用主包内的公共资源
9. 分包预下载
-
什么是分包预下载
分包预下载指的是:在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面时的启动速度。 -
配置分包的预下载
预下载分包的行为,会在进入指定的页面时触发。在app.json中,使用preloadRule节点定义分包的下载规则,示例代码如下:{
"preloadRule": { // 分包预下载的规则
"pages/contact/contact": { // 触发分包预下载的页面路径
// network表示在指定的网络模式下进行预下载
// 可选择:all(不限网络) 和 wife(仅wife模式下进行下载)
// 默认值:wife
"network": "all",
// packages:表示进入页面后,预下载哪些分包
// 可以通过root或name指定预下载哪些分包
"packages": ['packageA']
}
}
} -
分包预下载的限制
同一个分包中的页面享有共同的预下载大小限额2M。