项目做一个阶段性总结吧,针对代码,不针对业务
如果有更好的方案,欢迎交流
一、登入模块
一般情况下,用户权限信息会在app.js请求
App({
onLaunch() {
// 获取code 获取openid 再查询个人信息(权限)
}
})
但是我们app.js接口请求时,异步,页面与小程序生命周期执行顺序是不受控制的。尤其当你的首页部分数据是需要个人权限信息来渲染的。
小程序新建项目的时候,官方有个解决方案是回调。
但是如果微信小程序第一次首页跳转就是index页面时,是没有问题的。可你分享其他页面的时候(还是权限问题,是游客还好),总不能每次都加一个回调。而且,如果你在该页面/index回调里写请求接口,只能触发运行一次;如果你第一次跳到其他页面,再回到/index,回调内的接口是不走的,还要跟上图类似,还要做判断,数据请求是否请求到数据,没请求还要再做一次请求。个人感觉很乱,也烦。
个人方案
加了一个过渡页面/pages/welcome/welcome,
app.js
App({
onLaunch() {
// 获取code 获取openid 再查询个人信息
const url = (getCurrentPages()[getCurrentPages().length - 1].route)
wx.reLaunch({
url: url === 'pages/welcome/welcome' ? '/pages/home/home' : url, // 如果是程序默认首页路径配置是welocome, 就跳转真的首页/home,如果是其他页面,就跳到对应页面,反正此时用户权限接口完成(可能会有点闪)
})
}
})
此时welcome页面是默认页面,没有任何逻辑,只是占位。关键在于当app.js用户权限请求完成时,来触发页面跳转。
在我看来,确实如此是完美解决问题,但是,但是,有一个问题。我分享其他页面的时候,左上角是小房子,点击回到首页是welcome页面。
我现在加了一个全局属性来判断,做welocme跳转
App({
onLaunch() {
this.globalData.isGetUserApi = false;
// 获取code 获取openid 再查询个人信息
this.globalData.isGetUserApi = true;
const url = (getCurrentPages()[getCurrentPages().length - 1].route)
wx.reLaunch({
url: url === 'pages/welcome/welcome' ? '/pages/home/home' : url,
})
},
globalData: {
isGetUserApi: false, // app.js中获取用户信息是否请求完成
}
})
welcome
onShow: function () {
if(getApp().globalData.isGetUserApi){
const url = (getCurrentPages()[getCurrentPages().length - 1].route)
wx.reLaunch({
url: url === 'pages/welcome/welcome' ? '/pages/home/home' : url,
})
}
},
这样有问题
会报错
fail page \"pages/***/pages/***/***\" is not found
修改如下
const url = '/' + (getCurrentPages()[getCurrentPages().length - 1].route) // 路径要绝对路径
但是还有一个小问题,route只是把路径取出,但是动态拼接的query?xx=xxx&xx=xxx
不会一起取出
const options = getCurrentPages()[getCurrentPages().length - 1].options
let urlData = '';
for (let key in options) {
urlData += (key + '=' + options[key] + '&')
}
授权用户手机号
此处用的是vant
<van-button color="#DC3538" round block size="normal" style="margin: 40rpx 0" open-type="getPhoneNumber" lang="zh_CN" bindgetphonenumber="getPhoneNumber" >授权</van-button>
// app.js
wx.login({
success: res => {
if (res.errMsg === 'login:ok') {
const code = res.code
getOpenId({
js_code: code
}).then(res => { // 走接口根据code获取openId session_key
const data = JSON.parse(res.data)
if (!data.errcode && res.code === '0') {
wx.showToast({
title: '小程序初始化',
icon: 'loading'
})
this.globalData.openId = (JSON.parse(res.data)).openid // 后台不愿转,只能自己转了
this.globalData.session_key = (JSON.parse(res.data)).session_key
globalData: {
openId: null
session_key: null, // app.js中获取用户信息是否请求完成
}
// 授权页面
getPhoneNumber(e) {
const that = this;
if (e.detail.errMsg === "getPhoneNumber:ok") {
const data = {
encryptedData: e.detail.encryptedData,
iv: e.detail.iv,
session_key: getApp().globalData.session_key
}
wx.checkSession({
success() {
getUserPhone(data).then(res => {
if (res.code === '0') {
const result = JSON.parse(res.data)
getApp().globalData.userInfo.phone = (result.phoneNumber)
}
})
},
fail() {
wx.showToast({
title: 'session_key 过期',
})
wx.login({
// 重新来获取
})
}
})
}
},
wxs
后端字段返回格式,不是前端想要的格式,在页面上写逻辑,逻辑正确但是不出效果
xml
<wxs src="../../utils/format.wxs" module="tools" />
<view>{{tools.xx(xx)}}</view>
组件传值
父传子 属性传值
// 父
<component array="{{ array }}"></component>
// 子
properties: {
array: array,
},
父组件调用子组件方法
// 父
<component id="component"></component>
this.selectComponent("#component").functionName
子传父
// 子
chooseSpecification(e) {
this.triggerEvent('changeMoney', {
money: money
})
},
// 父
<component bind:changeMoney="changeMoney"></component>
changeMoney(e) {
console.log(e.detail.money)
},
input绑定值
简单的,还是用双向绑定 model:value
, 还是可以省一些代码量
列表 详情 状态切换
数据请求优化和详情状态更新返回列表
好比页面有状态,进列表页仍然是tab
正常处理,一开始会在url是拼接类型值,列表页onload生命周期,options取出类型,走列表接口。之后tab监听点击事件再走对应接口。
我这里是用van-tab change事件监听的,会出现页面走两次接口,第一次onload,第二次change事件。
<van-tabs active="{{ tabActive}}" bind:change="onTabChange"></van-tabs>
onLoad: function (options) {
const {
status
} = options;
this.setData({
tabActive: status,
})
},
onShow: function () {
this.getList() // 详情状态更新返回列表,列表也要对应更新
},
onTabChange(e) {
if (e.detail.name == this.data.tabActive) {
return
}
this.setData({
tabActive: e.detail.name
})
this.getList()
},
getList() {
this.setData({
orderList: []
})
wx.showLoading({
title: '数据加载中',
})
getOrderList(this.data.tabActive).then(res => {
if (res.code == '0') {
wx.hideLoading()
this.setData({
orderList: res.data
})
} else {
wx.hideLoading()
}
})
},
页面分享
如果是静态值,没问题,但是如果分享链接中有动态值
onShareAppMessage: function (options) {
if (options.from === "button") {
return new Promise(function (resolve, reject) { // 之前一个版本是没有Promise,是返回不了自定义分享对象
getInviteCode().then(res => { // 接口请求
if (res.code === '0') {
const code = res.data;
resolve({
title: xxx+ '邀请您加入',
path: '/pages/register/register?shareCode=' + code + '&role=3',
imageUrl: 'xxx'
})
}else{
reject(res)
}
})
})
}
},
组件动态数据传递
动态数据我这里指比如app.js请求的数据,不能直接像页面传值getApp().globalData;我是在页面赋值,利用properties传值。
复制文本,默认弹框
textPaste(e) {
const orderid = e.currentTarget.dataset.orderid;
wx.setClipboardData({
data: orderid,
success: function (res) {
wx.hideToast();
wx.getClipboardData({ //这个api是把拿到的数据放到电脑系统中的
success: function (res) {
wx.showToast({
title: '复制成功',
duration: 2000
})
console.log(res.data) // data
}
})
}
})
},
暂时先写这么多,后续有补充的再补充