目前,小程序中已经支持使用 npm 安装第三方包,从而来提高小程序的开发效率。但是,在小程序中使用 npm 包有如下 3 个限制:
总结:虽然 npm 上的包有千千万,但是能供小程序使用的包却 “为数不多” 。
在小程序项目中,安装 Vant 组件库主要分为如下 3 步:
官方快速上手教程:https://youzan.github.io/vant-weapp/#/quickstart#an-zhuang
安装完 Vant 组件库之后,可以在 app.json
的 usingComponents
节点中引入需要的组件,即可在 wxml 中直接使用组件。示例代码如下:
// app.json
"usingComponents": {
"van-button": "@vant/weapp/button/index"
}
// 某页面 .wxml 结构
<van-button type="danger">危险按钮</van-button>
前提知识:需要知道CSS 变量的基本用法,请参考 MDN 文档:CSS变量
在 app.wxss
中,写入 CSS 变量,即可对全局生效:
/* app.wxss */;
/* 这个page 是微信app根元素 */
page {
/* 定制警告按钮的背景色和边框颜色 */
--button-danger-background-color: red;
--button-danger-border-color: #000;
}
所有可用的颜色变量,请参考 Vant 官方提供的配置文件:地址
在小程序中,实现 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 api
promisifyAll(wx, wxp)
// 页面的 .wxml 结构
<van-button type="default" bindtap="getInfo">默认按钮</van-button>
// 在页面的 .js 文件中 , 定义响应的 tap事件处理函数
async getInfo() {
const res = await wx.p.request({
url: 'https://www.escook.cn/api/get',
method: 'GET',
data: {
name: 'zs'
}
});
console.log(res);
}
在小程序中,可使用 mobx-miniprogram
配合 mobx-miniprogram-bindings
实现全局数据共享。其中:
在项目中运行如下的命令,安装 MobX 相关的包:
npm install --save mobx-miniprogram mobx-miniprogram-bindings
注意:MobX 相关的包安装完毕之后,重新构建 npm(在开发者工具的左上角的工具栏)
在项目根目录新建 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;
})
})
// 某页面的 .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();
},
})
// 某页面的 .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);
}
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings';
import { store } from '../../store/store'
Component({
behaviors: [storeBindingsBehavior], // 通过 storeBindingsBehavior 来实现自动绑定
storeBindings: {
store, // 指定要绑定的store
fields: { // 指定要绑定的字段数据
numA: () => store.numA, // 绑定数据的第一种方式
numB: (store) => store.numB, // 绑定数据的第二种方式
sum: 'sum', // 绑定数据的第三种方式
},
actions: { // 指定要绑定的方法
updateNum2: 'updateNum2',
updateNum1: 'updateNum1'
}
}
})
// 组件的 .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);
},
}
分包前,小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的下载时间。
分包后,小程序项目由 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"
]
}
]
}
subpackages
的配置进行分包,subpackages 之外的目录将被打包到主包中独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其他分包而单独运行。
独立分包和普通分包的区别:是否依赖于主包才能运行
开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中原因如下:
注意:一个小程序中可以有多个独立分包。
假设小程序目录结构如下:
├── 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
}
]
}
独立分包和普通分包以及主包之间,是相互隔绝的,不能相互引用彼此的资源!例如:
分包预下载指的是:在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面时的启动速度。
预下载分包的行为,会在进入指定的页面时触发。在 app.json
中,使用 preloadRule
节点定义分包的预下载规则,示例代码如下:
"preloadRule": { // 分包预下载的规则
"pages/index": { // 触发分包预下载的页面路径
// network 表示在 指定的网络模式下进行预下载
// all(不限网络), wifi(仅wifi模式下可预下载)
"network": "all",
// packages 表示进入页面后,预下载哪些分包
// 可以通过 root 或者 name 指定预下载哪些分包
"packages": ["pagA"]
}
}
同一个分包中的页面享有共同的预下载大小限额 2M,例如: