目录
一、npm包
1、Vant Weapp
(1)安装Vant组件库
(2)使用Vant组件
(3)定制全局主题样式
2、API Promise化
(1)基于回调函数的异步API的缺点
(2)API Promise化
(3)调用Promise化之后的异步API
二、全局数据共享
1、小程序中的全局数据共享方案
2、MobX
(1)安装MobX相关的包
(2)创建MobX的Store实例
(3)将Store中的成员绑定到页面中
(4)在页面上使用Store中的成员
(5)将Store中的成员绑定到组件中
(6)在组件中使用Store中的成员
三、分包
1、分包加载规则
2、分包的体积限制
3、使用分包
(1)配置方法
(2)打包原则
(3)引用原则
4、独立分包
(1)应用场景
(2)配置方法
(3)引用原则
5、分包预下载
(1)配置分包预下载
(2)分包预下载的限制
目前,小程序中已经支持使用npm 安装第三方包,从而来提高小程序的开发效率。但是,在小程序中使用npm包有如下3个限制:
Vant Weapp是有赞前端团队开源的一套小程序U组件库,助力开发者快速搭建小程序应用。它所使用的是MIT开源许可协议,对商业使用比较友好。
官方文档地址:介绍 - Vant Weapp (youzan.github.io)
在小程序项目中,安装Vant组件库主要分为如下3步:
详细的操作步骤,大家可以参考Vant官方提供的快速上手教程:
快速上手 - Vant Weapp (youzan.github.io)
安装完Vant组件库之后,可以在 app.json的usingComponents 节点中引入需要的组件,即可在 wxml中直接使用组件。示例代码如下:
Vant weapp使用CSS变量来实现定制主题。关于CSS变量的基本用法,请参考MDN文档:使用 CSS 自定义属性(变量) - CSS(层叠样式表) | MDN (mozilla.org)
在app.wxss中,写入CSS变量,即可对全局生效:
page为每个页面的根节点,此处代表其作用域,属性的名字是定制的
vant-weapp/var.less at dev · youzan/vant-weapp · GitHub
默认情况下,小程序官方提供的异步API都是基于回调函数实现的,例如,网络请求的APl需要按照如下的方式调用:
缺点:容易造成回调地狱的问题,代码的可读性、维护性差!
APl Promise化,指的是通过额外的配置,将官方提供的、基于回调函数的异步API,升级改造为基于Promise的异步API,从而提高代码的可读性、维护性,避免回调地狱的问题。
在小程序中,实现APl Promise 化主要依赖于miniprogram-api-promise这个第三方的npm包。它的安装和使用步骤如下:
终端中执行--->
npm i --save [email protected]
然后构建npm
然后--->
//app.js
//在小程序入口文件中(app.js),只需调用一次 promisifyAll()方法,
//即可实现异步API的Promise化
import { promisifyAll } from 'miniprogram-api-promise' // es6语法
const wxp = wx.p = {}
promisifyAll(wx, wxp)
把wx身上所有基于回调函数的异步API进行Promise化,然后把它们挂载到wxp这个空对象身上,今后,在每个小程序的页面中,就可以基于wx这个顶级对象的一个自定义属性wx.p去调用那些Promise化之后的API了。
全局数据共享(又叫做:状态管理)是为了解决组件之间数据共享的问题。开发中常用的全局数据共享方案有: Vuex、Redux、MobX等。
在小程序中,可使用mobx-miniprogram配合mobx-miniprogram-bindings 实现全局数据共享。其中:
在项目中运行如下的命令,安装MobX相关的包:
npm install --save [email protected] [email protected]
然后记得构建npm 。
创建一个store文件夹,专门用来储存跟MboX相关的js文件,
解释:从mobx-miniprogram导入observable方法,调用这个方法,它的返回值就是一个store实例对象,在创建store实例对象期间,我们可以挂载一些共享的数据
导入store就可以使用里面的numA和numB了。
计算属性 --->(看注释)
// 在这个 JS 文件中,专门来创建 Store 的实例对象
import {observable} from 'mobx-miniprogram'
export const store = observable({
// 数据字段
numA: 1,
numB: 2,
activeTabBarIndex: 0,
// 计算属性
// 当numA或者numB发生变化的时候,都需要重新计算sum的值
// 定义一个方法,这个方法的名字就是计算属性的名字,
// 修饰符get表示,当这个计算属性的值是只读的,因为计算属性的值不需要被重新赋值
// 它的值是依赖于数据字段的变化来自动进行计算的,return的就是最后计算属性的值
get sum() {
return this.numA + this.numB
}
})
action方法--->
从mobx-miniprogram导入action方法
// 在这个 JS 文件中,专门来创建 Store 的实例对象
import { observable, action } from 'mobx-miniprogram'
export const store = observable({
// 数据字段
numA: 1,
numB: 2,
activeTabBarIndex: 0,
// 计算属性
get sum() {
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: function (options) { // 生命周期函数--监听页面加载
// 返回值作用,在页面被卸载的时候做一些清理性质的工作
this.storeBindings = createStoreBindings(this, { // 这些绑定到this(此页面上)
store, // 数据源
fields: ['numA', 'numB', 'sum'], // 数据字段
actions: ['updateNum1'] // 方法
})
},
onUnload: function () { // 生命周期函数--监听页面卸载
this.storeBindings.detroyStoreBindings()
}
})
{{numA}} + {{numB}} = {{sum}}
numA + 1
numA - 1
// 页面js文件中
btnHandler1(e) {
// console.log(e)
this.updateNum1(e.target.dataset.step)
},
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
import { store } from '../../store/store'
Component({
// 通过storeBindingsBehavior来实现自动绑定
behaviors: [storeBindingsBehavior],
storeBindings: {
// 数据源
store, // 指定要绑定的Store
fields: { // 要绑定的字段数据
numA: 'numA',
numB: 'numB',
sum: 'sum'
// 或 sum:()=>store.sum, // 返回store.sum
// 或 sum:(store)=>store.sum,
},
actions: { // 要绑定的方法
updateNum2: 'updateNum2'
}
}
})
{{numA}} + {{numB}} = {{sum}}
numB + 1
numB - 1
// components/numbers/numbers.js
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
import { store } from '../../store/store'
Component({
// 通过storeBindingsBehavior来实现自动绑定
behaviors: [storeBindingsBehavior],
storeBindings: {
// 数据源
store, // 指定要绑定的Store
fields: { // 要绑定的字段数据
numA: 'numA',
numB: 'numB',
sum: 'sum'
// 或 sum:()=>store.sum, // 返回store.sum
// 或 sum:(store)=>store.sum,
},
actions: { // 要绑定的方法
updateNum2: 'updateNum2'
}
},
/**
* 组件的方法列表
*/
methods: {
btnHandler2(e) {
this.updateNum2(e.target.dataset.step)
}
}
})
分包指的是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。
对小程序进行分包的好处主要有以下两点:
分包前:
分包前,小程序项目中所有的页面和资源都被打包到了一起,导致整个项目体积过大,影响小程序首次启动的下载时间。
分包后:
分包后,小程序项目由1个主包+多个分包组成:
在小程序启动时,默认会下载主包并启动主包内页面
当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示
目前,小程序分包的大小有以下两个限制:(具体限制会有所变化,以官方为准)
如何看体积------>
详情->基本信息->
在app.json的subpackages节点中声明分包的结构
"subpackages":[
{
"root": "pkgA", // 分包的根目录(必写)
"name": "p1", // 分包的别名(可写可不写)
"pages": [ // 当前分包下,所有页面的相对存放路径(必写)
"pages/cat/cat"
]
},
{
"root": "pkgB",
"name": "p2",
"pages": [
"pages/mango/mango"
]
}
]
独立分包本质上也是分包,只不过它比较特殊,可以独立于主包和其他分包而单独运行。
一个小程序中可以有多个独立分包。
开发者可以按需,将某些具有一定功能独立性的页面配置到独立分包中。原因如下:
通过independent声明独立分包
"subpackages":[
{
"root": "pkgA",
"name": "p1",
"pages": [
"pages/cat/cat"
],
"independent": true // 当前分包为独立分包
}
]
独立分包和普通分包以及主包之间,是相互隔绝的,不能相互引用彼此的资源!主包中的公共资源也不行!!!
分包预下载指的是:在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面时的启动速度。
预下载分包的行为,会在进入指定的页面时触发。在 app.json中,使用preloadRule 节点定义分包的预下载规则,示例代码如下:
"preloadRule": { // 分包预下载的规则
"pages/contact/contact":{ // 触发分包预下载的页面路径
// network表示在指定的网络模式下进行预下载
// 可选值为:all(不限网络)和wifi(仅wifi模式下进行预下载)
// 默认值为:wifi
"network": "all",
// packages表示进入页面后,预下载哪些分包
// 可以通过root或者name指定预下载哪些分包
"packages": ["pkgA"]
}
}
进入contact页面后,Console为:
wifi选项:
同一个分包中的页面享有共同的预下载大小限额2M。(具体限制会有所变化,以官方为准)
---------------------------------------------------------------------------------------------------------------------------------
到此结束,接下来对照检验学习成果------------->
---------------------------------------------------------------------------------------------------------------------------------