1.基于Promise的API
1.1 基于回调函数API的缺点
- 默认情况下,小程序官方提供的API都是基于回调函数实现的。 缺点:会造成回调地狱的情况,比如:使用原生的小程序API发送请求
clickSendRequest(){
wx.request({
url: 'url',
method:'', //请求方式
data: {}, //请求携带的参数
success: () => {}, //请求成功后的回调
fail: () => {}, // 请求失败后的回调
complete: () => {} //请求完成后的回调
})
}
1.2 什么是API promise化?
- API的promise化,指的是通过额外的配置,将官方提供的、基于回调函数的异步 API,升级改造为基于 Promise 的异步 API,从而提高代码的可读性、维护性,避免回调地狱的问题
1.3 实现小程序API的promise化
- 通过安装 miniprogram-api-promise实现promise化,安装命令 npm install --save miniprogram-api-promise@版本号
- 在app.json文件中引入 miniprogram-api-promise
// app.json
import { promisifyAll } from "miniprogram-api-promise"
// 定义空对象用来接收wx实例对象
const wxp = wx.p = {}
// promisifyAll()接受两个参数,第一个参数页面的实例wx,第二个参数为空对象接收页面的实例wxp
promisifyAll(wx,wxp)
- 在方法中发送请求测试
// 点击发送请求
async btnSendRequest(){
// 使用await等待请求结果的返回,async修饰的函数返回的结果为promise
const { data: res } = await wx.p.request({
method: 'GET',
url: '', //请求的路径
success: () => {}, //请求成功的回调函数
fail: () => {}, //请求失败的回调函数
complate: () => {} //请求完成后的请求
})
console.log(res)
}
2. 小程序中支持es7的async语法
- async和await是解决回调的最终方案
- 在小程序中使用facebook的regenerator库的步骤
- (1) 首先需要在小程序开发工具中勾选es6转es5语法
- (2) 接着下载facebook的regenerator库中的
runtime/runtime.js文件 - 可以去这里下载github.com/facebook/re…
- (3) 在小程序项目根目录下新建
lib/runtime/runtime.js文件目录结构,把facebook中的runtime.js代码复制到小程序runtime.js中 - (4) 在小程序项目中,那个页面需要使用
async语法,引入runtime.js文件(不能全局引入) - (5) 使用案例
-
- 封装的请求接口
// 封装的请求接口 request.js export const request = (params) => { // 定义接口的基础路径 const baseUrl = "https://www.baidu.com/api/v1" return new Promise((resolve,reject)=>{ wx.request({ ...params url: parmas.url + baseUrl, success: (res) => { resolve(res) }, fail: (error) => { console.log(error) } }) }) }- 2.页面中使用封装的接口,发送请求,获取数据
// 引入封装的接口请求 import { request } from '../../api/request.js' import { regeneratorRuntime } from '../../lib/runtime' // 接口发送请求获取数据 Page({ data:{ username: '', //定义存储用户名变量 }, onLoad(){ this.getData() }, async getData(){ // 定义发送请求,await等待接口返回数据的响应 const res = await wx.request({url:'/username', method: 'GET'}) if(res.code === 200){ this.setData({ username: res.data.username }) } } }) -
3.全局数据共享Mobx
3.1 安装npm包
- mobx-miniprogram:相当于数据共享仓库,用于存放各种数据,方便用户存取操作。
- mobx-miniprogram-bindings:介于数据共享仓库和组件之间的桥梁,使二者能够相互联系。
- cmd: npm i --save mobx-miniprogram mobx-miniprogram-bindings
- 安装完成后删除项目原有的miniprogram_npm ,小程序开发工具中重新npm构建项目
3.2 在页面中使用store mobx
- 新建根文件夹store并创建store.js文件存放mobx实例
// 创建store实例对象
import { observable } from "mobx-miniprogram"
export const store = observable({
// 全局数据字段
numA: 1,
numB: 2,
// 计算属性
get sum(){
return this.numA + this.numB
},
// action函数修改数据
updateNumberA: action(function(val){
this.numA += val
}),
updataNuberB: action(function(val){
this.numB += val
})
})
- 注意:考虑到数据的管理和安全,mobx store里的数据不允许外界直接修改,必须通过store对象中的action函数修改
2.3 在index.js中引入全局仓库中的数据
// pages/index/index.js
// 在当前js中引入数据仓库
import { store } from "../../store/store"
// 使用**mobx-miniprogram-bindings**搭建页面与数据仓库之间的桥梁
import { createStoreBindings } form "mobx-miniprogram-binds"
Page({
onLoad(){
// createStoreBindings方法接收两个参数,参数1:将数据绑定到的地方,this指的是当前页面
// 第二个参数:为数据仓库中绑定的数据、方法
// this.storeBindings自定义添加一个方法,来接收数据仓库中的数据
this.storeBindings = createStoreBindings(this,{
store,
fields:{
numA: 'numA',
numB: (store)=> store.numB
sum: () => sum
},
actions: ['updateNumberA','updateNumberB']
})
}
})
3.4 在index.wxml中使用 index.js中接收仓库的数据
<!-- pages/index/index.wxml -->
<!-- 使用mobx定义的全局数据 -->
<view>{{numA}} + {{numB}} = {{sum}}</view>
<van-button type="info" bindtap="btnadd" data-step="{{1}}">numA+1</van-button>
<van-button type="warning" bindtap="btnminues" data-step="{{-1}}">numB-1</van-button>
3.5 在index.js页面中修改仓库中数据字段的值
// pages/index/index.js
Page({
onLoad(){
this.storeBindings = createStoreBindings(this,{
...
})
},
// numA+1
btnaaa(e){
// e.target.dataset.step 获取事件绑定时传递的参数
this.updateNumberA(e.target.dataset.step)
},
// 修改numB-1
btnminues(e){
this.updateNumberB(e.target.dataset.step)
}
})
4.在组件中使用store mobx
4.1 新建组件test,配置为全局的组件,在pages/index/index.wxml中使用test组件
<!--components/test/test.wxml-->
<view>
<view>{{numA}} + {{numB}} = {{sum}}</view>
<van-button type="info" bindtap="btnadd" data-step="{{1}}">numA+1</van-button>
<van-button type="warning" bindtap="btnminues" data-step="{{-1}}">numB-1</van-button>
</view>
<!-- pages/index/index.wxml -->
<!-- 在index页面使用全局组件test -->
<test></test>
4.2 在components/test/test.js文件中使用全局数据
// components/test/test.js
// 引入全局的数据仓库
import { store } from "../../store/store";
// 使用storeBindingBehavior搭建页面与数据之间的桥梁
import { storeBindingsBehavior } from "mobx-miniprogram-bindings";
Component({
// 在behavior添加storeBindingBehavior来做绑定功能
behaviors: [storeBindingsBehavior],
// 配置对象
storeBindings:{
store:store,
fields: {
numA: 'numA',
numB: 'numB',
sum: 'sum'
},
actions: [ "updateNumberA","updateNumberB" ]
},
/**
* 组件的方法列表
*/
methods: {
// 修改numA值加1的方法
btnadd(e){
this.updateNumberA(e.target.dataset.step)
},
// 修改numB值减1的方法
btnminues(e){
this.updateNumberB(e.target.dataset.step)
}
}
})
5. 分包
5.1 分包加载
- 某些情况下,开发者需要将小程序划分成不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。
- 在构建小程序分包项目时,构建会输出一个或多个分包。每个使用分包小程序必定含有一个主包。所谓的主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本;而分包则是根据开发者的配置进行划分
- 在小程序启动时,默认会下载主包并启动主包内页面,当用户进入分包内某个页面时,客户端会把对应分包下载下来,下载完成后再进行展示。目前小程序分包大小有以下限制
- 整个小程序所有分包不能超过20M
- 单个分包/ 主包不能超过2M
- 对小程序进行分包,可以优化小程序首次启动的下载时间,
5.2 使用分包
- 在app.json中的subpackages字段声明分包的结构
"subPackages": [
{
"root": "packageA",
"name": "pckA",
"pages": [
"pages/cat/cat",
"pages/pig/pig"
]
},
{
"root": "packageB",
"name": "pckB",
"pages": [
"pages/apple/apple",
"pages/grape/grape"
]
}
],
- subpackages中,每个分包的配置有以下几项
- root: 分包的目录
- name: 分包别名,分包预下载时可以使用
- pages:分包页面路径,相对于分包根路径
- independent: 分包是否时独立分包
5.3 打包原则
- 声明subpackages后,将按照subpackages配置路径进行打包,subpackages配置路径外的目录将被打包到主包中
- subpackages 的根路径不能是另外一个subpackages内的子目录
- tabBar 必须在主包内
5.4 引用原则
-
packageA无法 require packageB JS文件,但可以require主包、packageA内的JS文件;使用分包异步化时不受此条限制。
-
packageA无法 importpackageB的 template,但可以 require 主包、packageA内的 template -
packageA无法使用packageB的资源,但可以使用主包、packageA内的资源
5.5 独立分包
- 独立分包属于分包的一种,普通分包的所有限制都对独立分包有效。
- 在
app.json的subpackages字段中对应的分包配置项中定义independent字段声明对应分包为独立分包。
"subPackages": [
{
"root": "packageA",
"name": "pckA",
"pages": [
"pages/cat/cat",
"pages/pig/pig"
]
},
{
"root": "packageB",
"name": "pckB",
"pages": [
"pages/apple/apple",
"pages/grape/grape"
],
"independent": true
}
],
5.6 分包预下载
- 配置方法:预下载分包行为在进入某个页面时触发,通过在
app.json增加preloadRule配置来控制
"preloadRule":{
"pages/index/index":{
"network": "all",
"packages": "pckA"
}
}
-
preloadRule中,key是页面路径,value是进入此页面的预下载配置,每个配置有以下几项 1.packages 进入页面后预下载分包的root或name 2.network 在指定网络下预下载,可选值为 all | wife
frailscholar