简单上手微信小程序使用npm包使用Vant Wapp、API Promise化、全局数据共享、分包基础
一、简介:
小程序对 npm 的 支持与限制
目前,小程序已经支持npm 安装第三方包,从而提高小程序的开发效率,但是在小程序中使用npm 包有如下3个限制
- 不支持依赖于 Node.js 内置库的包
- 不支持依赖于浏览器内置对象的包
- 不支持依赖于C++插件的包
总结:虽然 npm 上的包千千万万,但是能提供给小程序的包却 “为数不多”
二、安装vant组件库及使用
注意:使用npm 需要有node环境, 不识别命令的需要安装node (node下载官网:http://nodejs.cn/download/)
先初始化npm
npm init -y
接下来通过以下步骤快速上手Vant - Webapp(官方文档:https://youzan.github.io/vant-weapp/#/quickstart)
步骤一 通过 npm 安装
# 通过 npm 安装 建议指定版本 npm i @vant/weapp@1.3.3 -S --production # 通过 yarn 安装 yarn add @vant/weapp@1.3.3 --production
建议制定版本
步骤二 修改app.json
将 app.json 中的 "style": "v2"
去除,小程序的新版基础组件强行加上了许多样式,难以覆盖,不关闭将造成部分组件样式混乱。
步骤三
步骤三 修改 project.config.json
开发者工具创建的项目,miniprogramRoot
默认为 miniprogram
,package.json
在其外部,npm 构建无法正常工作。
需要手动在 project.config.json
内添加如下配置,使开发者工具可以正确索引到 npm 依赖的位置。
{ ... "setting": { ... "packNpmManually": true, "packNpmRelationList": [ { "packageJsonPath": "./package.json", "miniprogramNpmDistDir": "./miniprogram/" } ] } }
注意: 由于目前新版开发者工具创建的小程序目录文件结构问题,npm构建的文件目录为miniprogram_npm,并且开发工具会默认在当前目录下创建miniprogram_npm的文件名,所以新版本的miniprogramNpmDistDir配置为'./'即可
步骤四 构建 npm 包
打开微信开发者工具,点击 工具 -> 构建 npm,并勾选 使用 npm 模块 选项,构建完成后,即可引入组件。
步骤五 typescript 支持
如果你使用 typescript 开发小程序,还需要做如下操作,以获得顺畅的开发体验。
安装 miniprogram-api-typings
# 通过 npm 安装 npm i -D miniprogram-api-typings # 通过 yarn 安装 yarn add -D miniprogram-api-typings
在 tsconfig.json 中增加如下配置,以防止 tsc 编译报错。
请将path/to/node_modules/@vant/weapp
修改为项目的 node_modules
中 @vant/weapp 所在的目录。
{ ... "compilerOptions": { ... "baseUrl": ".", "types": ["miniprogram-api-typings"], "paths": { "@vant/weapp/*": ["path/to/node_modules/@vant/weapp/dist/*"] }, "lib": ["ES6"] } }
使用组件,以Button组件为例
只需要在app.json
或index.json
中配置 Button 对应的路径即可。
所有组件文档中的引入路径均以 npm 安装为例,如果你是通过下载源代码的方式使用 @vant/weapp,请将路径修改为项目中 @vant/weapp 所在的目录。
// 通过 npm 安装 // app.json "usingComponents": { "van-button": "@vant/weapp/button/index" }
// 通过下载源码使用 es6版本 // app.json "usingComponents": { "van-button": "path/to/@vant/weapp/dist/button/index" }
// 通过下载源码使用 es5版本 // app.json "usingComponents": { "van-button": "path/to/@vant/weapp/lib/button/index" }
使用按钮
// wxml中直接使用 <van-button type="primary">按钮</van-button>
三、使用 npm 包 - API Promise
1. 基于回调函数的异步 API 的缺点
默认情况下,小程序官方提供的异步 API 都是基于回调函数实现的,例如,网络请求的 API 需要按照如下的方式调用:
缺点:容易造成回调地狱的问题,代码的可读性、维护性差!
2. 什么是 API Promise 化
API Promise化,指的是通过额外的配置,将官方提供的、基于回调函数的异步 API,升级改造为基于 Promise 的异步 API,从而提高代码的可读性、维护性,避免回调地狱的问题。
3. 实现 API Promise 化
在小程序中,实现 API Promise 化主要依赖于 miniprogram-api-promise 这个第三方的 npm 包。它的安装和使用步骤如下:
①、在项目根目录安装依赖包
npm i --save miniprogram-api-promise@1.0.4
建议:安装版本为1.0.4
②、在小程序入口文件app.js 中,只需调用promiseifyAll() 方法,即可实现异步API的Promise化
import {promisifyAll} from 'miniprogram-api-promise' const wxp = wx.p = {} promisifyAll(wx,wxp)
③、调用 Promise 化之后的异步 API
//页面.wxml结构 <van-button type="primary" bindtap="getInfo">按钮</van-button> //在页面.js 中定义getInfo()函数
async getInfo(){
const parmas = {
这样就完成小程序 Promise 化操作了
4、备注:
注意:记录一下构建失败的问题, 安装完包可能会存在构建失败,按照以下步骤在操作下应该就可以了
先删除①文件夹在(工具=> 构建npm)
四、全局数据共享
1、什么是全局数据共享
全局数据共享(又叫做: 状态管理)是为了解决组件之间数据共享的问题
开发中常用的数据共享方案有: Vuex ,Rudu,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
注意: Mbox相关的包安装完毕之后,记得删除 miniprogram_npm 目录后,重新构建 npm 具体操作如上面截图。
②、创建 Mbox 的 Store 实例
// 在这个 JS 文件中,专门来创建 store 实例对象 import { observable, action } from "mobx-miniprogram"; export const store = observable({ // 数据字段 numA: 1, numB: 2, // 计算属性 get sum() { return this.numA + this.numB }, // action 中的方法 用来修改 store 中的数据 updateNum1: action((step)=> { this.numA += step }), updateNum2: action((step)=> { this.numB += step }) })
注意:以上代码使用箭头函数导致报错所以改成下面写法就不报错了
// 在这个 JS 文件中,专门来创建 store 实例对象 import { observable, action } from "mobx-miniprogram"; export const store = observable({ // 数据字段 numA: 1, numB: 2, // 计算属性 get sum() { return this.numA + this.numB }, // action 中的方法 用来修改 store 中的数据 不能使用箭头函数否则报错 updateNum1: action(function(step) {this.numA += step }), updateNum2: action(function(step) { this.numB += step }) })
③、将 Store 中的成员绑定到页面中
// 页面的 .js文件 import { createStoreBindings } from "mobx-miniprogram-bindings"; import { store } from "../../store/store"; Page({ /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.storeBindings = createStoreBindings(this,{ store, fields: ['numA', 'numB', 'sum'], actions: ['updateNum1'] }) }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { this.storeBindings.destroyStoreBindings() }, })
④、在页面上使用 Store 中的成员
<!-- 页面的 .wxml 结构 --> <view>{{numA}} + {{numB}} = {{sum}}</view> <van-button type="primary" bindtap="btnHandle1" data-step="{{1}}">numA + 1</van-button> <van-button type="primary" bindtap="btnHandle1" data-step="{{-1}}">numA - 1</van-button> <!-- 按钮 tap 的点击事件处理函数 --> btnHandle1(e){ this.updateNum1(e.target.dataset.step) }
案例得出的结果如下:
⑤、将 Store 中的成员绑定到组件中
// components/numbers/numbers.js import { storeBindingsBehavior } from "mobx-miniprogram-bindings"; import { store } from "../../store/store"; Component({ behaviors: [storeBindingsBehavior], storeBindings: { // 数据源 store, fields: { numA: "numA", numB: "numB", sum: 'sum' }, actions: { updateNum2: 'updateNum2' } }, /** * 组件的方法列表 */ methods: { btnHandle2(e){ this.updateNum2(e.target.dataset.step) } } })
//.wxml
这次修改numB的值效果如下
五、分包 - 基础概念
1、什么是分包
分包指的是把一个完整的小程序项目, 按照需求划分不同的子包,在构建时打包不同的分包,用户在使用时按需加载
2、分包的好处
对小程序进行分包的好处主要是有以下两点
- 可以优化小程序首次启动的下载时间
- 在多团队共同开发时可以更好的解耦合作
3、分包前项目的构成
分包前,小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的下载时间
4、分包后项目的构成
分包后,小程序由1个主包 + 多个分包组成:
- 主包: 一般只包含项目的启动页面或TabBar页面,以及所有分包都需要用到的一些公共资源
- 分包: 只包含和当前分包有关的页面和私有资源
5、分包的加载规则
①、小程序启动时,默认会下载主包 并 启动主包内页面
- tabbar 页面需要放到主包中
②、当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后在进行展示
- 非 tabbar 页面可以按照功能的不同,划分不同的分包之后,按需加载
6、分包的体积限制
目前,小程序的大小有两个限制
- 整个小程序所有的大小不超过16M (主包 + 所有分包)
- 单个分包/主包大小不能超过 2M
7、使用分包
8、使用分包 - 打包规则
① 、小程序会按subpackages 的配置进行分包, subpackages 之外的目录将被打到主包中
②、主包也可以有自己的pages (即最外层的page字段)
③、tabBar 页面必须在主包内
④、分包之间不能互相嵌套
9、使用分包 - 引用原则
① 、主包无法引用分包内的私有资源
②、主包之间不能相互引用私有资源
③、分包可以引用主包内的公共资源
10、分包 - 独立分包
①、独立分包本质也是分包, 只不过他比较特殊,可以独立于主包和其他分包而单独运行。
②、独立分包和普通分包的区别
最主要的区别:是否依赖于主包才能运行
- 普通分包必须依赖于主包才能运行
- 独立分包可以在不下载主包的情况下,独立运行
③、独立分包的应用场景
开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中。原因如下
- 当小程序从普通的分包页面启动时,需要首先下载主包
- 而独立分包不依赖主包即可运行,可以很大程度上提升分包页面的启动速度
注意: 一个小程序中可以有多个独立分包。
④、独立分包的配置方法
⑤、独立分包的引用原则
独立分包和普通分包之间,是相互隔绝的,不能相互引用彼此的资源!例如:
- 主包无法引用独立分包内的私有资源
- 独立分包之间,不能相互引用私有资源
- 独立分包和普通分包之间,不能相互引用私有资源
- 特别注意: 独立分包中不能引用主包内的公共资源
11、分包 - 分包预下载
①、分包预下载指的是: 在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面的启动速度
②、配置分包的预下载,预下载分包的行为,会在进入指定的页面触发。在 app.js 中使用 preloadRule 节点定义分包的预下载规则,示例代码如下:
③、分包预下载的限制
同一个分包中的页面享有共同的预下载大小限额 2M;例如: