登陆流程的改变
原来我们在首次进入小程序时,会通过 getUserInfo 调起用户授权的弹窗,但是根据微信小程序,最新更新解释,开发工具,体验版本将不再支持这个授权方式而是通过 button 组件让用户自主去点击已完成授权目的(这个对开发者来说真的是很蛋疼),
解决方案: 设置一个用户登陆的过渡页面
<button wx:if="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="bindGetUserInfo">授权登录</button>
<view wx:else>请升级微信版本</view> //让用户自己去点击这个授权登录的按钮,然后再去进行后续的业务逻辑
小程序登陆逻辑
wx.login()
去获取用户的code
之后,发送code
给后台换取session_key
、unionid
、openid
这个请求的过程一般是在打开登陆界面的时候就已经调用了(此时已经取得了session_key
),当用户点击登陆的时候才会去调取登陆接口,拿获得session_key
去换取用户信息,此时还拿到了服务器返回的token
,用于用户以后的登陆,作为登陆的另外一个依据
code
临时登录凭证, 有效期五分钟, 通过wx.login()
获取session_key
会话密钥, 服务端通过code2Session
获取openId
用户在该小程序下的用户唯一标识, 永远不变, 服务端通过code
获取unionId
用户在同一个微信开放平台帐号(公众号, 小程序, 网站, 移动应用)下的唯一标识, 永远不变appId
小程序唯一标识appSecret
小程序的app secret
, 可以和code
,appId
一起换取session_key
// code 换取 session_key
async function fetchSessionKey(code) {
const { session_key, unionid, token, openid = '', user = {} } = await request(
{
url: '/api/app/v1/miniapp/session',
method: 'post',
data: { code }
}
)
user.session_key = session_key
user.unionid = unionid
user.openid = openid
authority.set(user)
if (token) {
user.token = token
authority.set(user)
const { back } = getCurrentOptions()
if (!back) return
wx.reLaunch({
url: decodeURIComponent(back)
})
} else {
const back = getCurrentUrl()
// 重定向登陆页面
if (!back.startsWith('/pages/login/main')) {
wx.redirectTo({
url: `/pages/login/main?back=${encodeURIComponent(back)}`
})
}
authority.set({ session_key, unionid })
}
return true
}
export default () => {
return new Promise((resolve, reject) => {
const user = authority.get() || {}
if (user.token) return resolve(user) // todo
const errorHandle = e => {
console.error(e)
wx.showToast({
title: '获取code失败',
icon: 'none'
})
reject(e)
}
wx.login({
success({ code }) {
fetchSessionKey(code)
.then(resolve)
.catch(errorHandle)
},
fail(e) {
errorHandle(e)
}
})
})
}
wx.getStorageSync And wx.setStorageSync
- 读取信息的时候要使用 try/catch 捕捉错误
- key 要唯一
- 清除数据之前要保存重要的信息: 用于登陆所需的信息
const key = 'user_info' // 定义储存的key,一定要确保是单一的
const maxAge = 1000 * 60 * 60 * 24 * 60 // 设置过期时间,60天过期
export default {
get() {
// 获取存储到localStorage中的数据,一般是用户信息,使用try/catch捕捉错误
try {
const user = wx.getStorageSync(key)
if (!user || user.time + maxAge < Date.now()) return null
// 如果储存的时间过期了,直接返回null,重新发送登陆接口获取
return user || {}
} catch (e) {
return {}
}
},
set(user) {
if (!user) return null
// 存储数据,没有数据直接返回null,外部捕捉这个null来判定是否成功
user.time = Date.now()
// 设置储存时间,用来判断是否过期
const oldUser = this.get() || {}
const newUser = { ...oldUser, ...user } //将以前的数据和新的数据一起整合在一起
console.log(newUser, 'newuser')
wx.setStorageSync(key, newUser) //微信存储数据的静态方法
return newUser
},
clear() {
const user = this.get() || {}
const { regionCode = '', currentCity = '', shop_id = '' } = user
// 即使是清除数据,也保存重要的登陆信息
wx.clearStorageSync()
this.set({ regionCode, currentCity, shop_id })
// 清空完之后再次储存
return user
}
}
登陆信息存储于本地
const key = 'user_info' // 定义储存的key,一定要确保是单一的
const maxAge = 1000 * 60 * 60 * 24 * 60 // 设置过期时间,60天过期
export default {
get() {
// 获取存储到localStorage中的数据,一般是用户信息,使用try/catch捕捉错误
try {
const user = wx.getStorageSync(key)
if (!user || user.time + maxAge < Date.now()) return null
// 如果储存的时间过期了,直接返回null,重新发送登陆接口获取
return user || {}
} catch (e) {
return {}
}
},
set(user) {
if (!user) return null
// 存储数据,没有数据直接返回null,外部捕捉这个null来判定是否成功
user.time = Date.now()
// 设置储存时间,用来判断是否过期
const oldUser = this.get() || {}
const newUser = { ...oldUser, ...user } //将以前的数据和新的数据一起整合在一起
wx.setStorageSync(key, newUser) //微信存储数据的静态方法
return newUser
},
clear() {
const user = this.get() || {}
const { regionCode = '', currentCity = '', shop_id = '' } = user
// 即使是清除数据,也保存重要的登陆信息
wx.clearStorageSync()
this.set({ regionCode, currentCity, shop_id })
// 清空完之后再次储存
return user
}
}
小程序表单和 video
小程序的坑: textarea 和 video 当被激活时他们的层级永远是最高的,无法去处理
textarea 的处理方法: 当需要在textarea
的上方加上一个弹窗活着页面时,需要手动的把textarea
隐藏,换一种方法来实现
video 暂时还不知道怎么处理,同时还要注意视频的播放问题,在离开页面的时候要强制的关闭视频
小程序实现下拉刷新的操作
async onPullDownRefresh() {
wx.showLoading();
....
// 相应的上拉事件处理函数
setTimeout(() => {
wx.hideLoading();
wx.stopPullDownRefresh();
}, 1000);
},
页面触底之后的上拉操作
async onReachBottom() {
// 首屏时只展示部分数据,未展示所有的数据
// 判断当前的数据量是不是后台接口返回的总数据量
if (this.List.length < this.total) {
// 数据没有完全被加载,上拉一次再次加载一次数据
this.pageData.page = this.pageData.page + 1;
const List = this.List;
const data = await fetchExpertsDetail(this.pageData);
this.List = [...answerList, ...data.answer]; // 合并新请求的数据和老的数据
} else {
// 如果全加载了,给个提示
console.log('到底啦');
}
},
小程序的路由跳转
要注意跳转到非 tabBar 页和 跳转到 tabBar 导航页
- 跳转到到导航页: wx.switchTab(Object object) 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
- 跳转到非导航页: wx.navigateTo(Object object) 保留当前页面,跳转到应用内的某个页面,使用 wx.navigateBack 可以返回到原跳转的页面,原页面没有被销毁。
- wx.redirectTo(Object object) 关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。
跳转的 query 参数
微信小程序的页面的query
参数是通过onLoad
获取的,mpvue
进行了优化,直接通过this.$root.$mp.query
获取相应的参数数据,其调用需要在onLoad
生命周期触发之后使用