几个微信小程序开发小技巧,提效又实用( 二 )


function request(opt) {return new Promise((resolve, reject) => {wx.request({...opt,success: res => { resolve(res)},fail: res => {reject(res)}})})}这里代码我们可以进一步改进,由于 success、fail 这里传入的参数只是由 resolve、reject 方法执行了下,所以可以直接传入 resolve、reject 方法即可 。
另外,由于其他小程序原生 API 格式一致,所以我们可以使用柯里化方法,来将其他需要进行 Promise 化的 API 进行处理:
function promisify(api) {return (opt = {}) => {return new Promise((resolve, reject) => {api({...opt,fail: reject,success: resolve})})}}然后,将柯里化方法执行的结果作为新的 Promise 化的 API 挂载到 wx.pro 对象上:
// 将指定 API 进行 Promise 化wx.pro.request = promisify(wx.request)// 使用wx.pro.request({...}).then(...)然后为了方便我们使用其他方法,可以循环将 wx 对象上可以被 Promise 化的方法比如 request、scanCode、showToast、getUserInfo 等一一挂载到 wx.pro 对象上,使用时可以直接 wx.pro.xx,由于这个方法执行返回的是一个 Promise 对象,因此可以像其它 Promise 化的对象那样使用 。
事实上,不知不觉,我们就自己实现了 wx-promise-pro 的源码,这个库的核心代码也就是上面那这几行
2.3 在项目中使用有了上面的工具后,我们可以将其使用在项目中,为了不在项目中遍布 wx.request 或 wx.pro.request 这里可以简单进行封装,新建两个文件如下:
// utils/api/fetch.js 封装请求方法、请求拦截器const app = getApp()const BaseUrl = 'http://172.0.0.1:7300/mock'const TokenWhiteList = ['/app/user/get-by-code'// 不需要鉴权的api手动添加到这里]/** * 设置请求拦截器 * @param params 请求参数 */const fetch = (params = {}) => {// 拦截器逻辑if (!TokenWhiteList.includes(params.url)) {params.header = {'content-type': 'application/json',// 默认值'token': app.globalData.token || ''}}if (params.url.startsWith('/')) {// 拼接完整URLparams.url = BaseUrl + params.url}// 返回promisereturn wx.pro.request({ ...params }).then(({ data: { code, message, data } }) => {// ... 各种异常情况的逻辑处理// 与后端约定 code 20000 时正常返回if (code === 20000) return Promise.resolve(data)return Promise.reject(message)})}export { fetch }然后再将所有 API 封装到单独的文件中集中管理:
// utils/api/apis.js 封装所有请求 APIimport { fetch } from './fetch'/* 根据微信code获取用户信息 */const appUserGetByCode = ({ code } = {}) => fetch({url: '/app/user/get-by-code',data: { code }})/* 扫码登录 */const appUserQrLogin = ({ qrCode } = {}) => fetch({method: 'POST',url: '/app/user/qr-login',data: { qrCode }})/* 个人信息 */const appUserInfo = () => fetch({url: '/app/user/info'})/* 系统参数获取,数据字典 */const appSysParamListByParam = () => fetch({url: '/app/sys-param/list-by-param'})/* 数据字典所有 */const appSysParamListAll = () => fetch({url: '/app/sys-param/list-all'})export {appSysParamListAll,// 数据字典所有appSysParamListByParam,// 系统参数获取,数据字典appUserGetByCode,// 根据微信code获取用户信息appUserQrLogin,// 扫码登录appUserInfo// 个人信息}在要使用 API 的地方就可以这样引入:
import * as Api from '../../utils/api/apis.js'// 相对路径// 使用方式Api.appSysParamListAll().then(({ dataList }) => this.upData({ sysParamList: dataList })).then(() => {const keyList = this.data.sysParamList.map(T => T.key)this.upData({keyList,formData: { keys: keyList }})})使用方式就很舒服,这里使用到了 upData,就是下面我要介绍的内容,是在下非常推介的小程序工具~
3. setState 修改 data 中想修改对象的属性在小程序中,data 是不能直接操作的,需要使用 setData 函数 。鉴于微信小程序开发时 setData 的使用体验十分蹩脚,我使用了个库函数 wx-updata,这个库函数在开发的时候对我很有帮助,这里特意推介给大家 。
3.1 为什么要使用 wx-updata你在使用 setData 的时候,是不是有时候觉得很难受,举个简单的例子:
// 你的 datadata: {name: '蜡笔小新',info: { height: 140, color: '黄色' }}如果要修改 info.height 为 155,使用 setData 要怎么做呢:
// 这样会把 info 里其他属性整不见了this.setData({ info: { height: 155 } })// 你需要取出 info 对象,修改后整个 setDataconst { info } = this.datainfo.height = 155this.setData({ info })似乎并不太复杂,但如果 data 是个很大的对象,要把比较深且不同的对象、数组项挨个改变:
data: {name: '蜡笔小新',info: {height: 140, color: '黄色',desc: [{ age: 8 }, '最喜欢大象之歌', '靓仔', { dog: '小白', color: '白色' }]}}


推荐阅读