小程序中是不支持路由攔截的,需要開發(fā)者自行封裝路由攔截的功能,實(shí)踐有許多的實(shí)現(xiàn)思路,下面我采用的是封裝組件的方式實(shí)現(xiàn)。比方說一個(gè)小程序項(xiàng)目只有一兩個(gè)頁面是不需要登錄就可以訪問的,其他頁面都是需要登錄之后才能訪問的,那我就用封裝一些邏輯來檢測用戶是否是登錄狀態(tài),如果不是則重定向到登錄頁,等用戶完成登錄后再跳轉(zhuǎn)到用戶本來要訪問的頁面。
主要實(shí)現(xiàn)原理:通過本地存儲(chǔ)的?token
?來判斷用戶的登錄狀態(tài),在小程序啟動(dòng)時(shí)讀取本地存儲(chǔ)并記錄到應(yīng)用實(shí)例當(dāng)中,方便其它頁面全局訪問:
主要步驟:
- 封裝名稱為?
authorization
?的組件 - 在生命周期函數(shù)onLaunch中讀取全局中記錄的?
token
?數(shù)據(jù) - 獲取當(dāng)前頁面的路徑,在未登陸的情況下通過地址參數(shù)傳給登錄頁面
// app.js
App({
onLaunch() {
//調(diào)用函數(shù) 讀取 token
this.getToken()
},
//封裝獲取token的函數(shù)
getToken() {
// 異步方式不會(huì)阻塞
wx.getStorage({
key: 'token',
success: ({ data }) => {
// this 指向應(yīng)用實(shí)例
this.token = data
},
fail() {},
})
}
})
封裝組件?
在根目錄創(chuàng)建?components/authorization
?目錄,然后在?app.json
?中全局注冊(cè)該組件:
{
...
"usingComponents": {
"authorization": "/components/authorization/index"
}
...
}
接下來在【房屋列表】頁面應(yīng)用?authorization
?組件:
<!-- house_pkg/pages/list/index.wxml -->
<authorization>
<block wx:if="{{true}}">
...
</block>
<view wx:else class="blank">
您還沒有認(rèn)證房屋,請(qǐng)點(diǎn)擊 <navigator hover-class="none" class="link" url=" ">添加</navigator>
</view>
</authorization>
當(dāng)前?authorization
?組件是沒有執(zhí)行任何邏輯的,接下來咱們?nèi)ソM件中添加插槽?slot
:
<!-- 用戶未登錄就不顯示頁面的內(nèi)容 -->
<slot wx:if="{{isLogin}}"></slot>
此時(shí)跳轉(zhuǎn)到【房屋列表】時(shí)會(huì)出現(xiàn)空白的內(nèi)容,原因是?isLogin
?的值當(dāng)前為?undefined
?即為?false
?假值。
讀取登錄狀態(tài)
在上面isLogin
?的數(shù)并未進(jìn)行初始化且為假值,接下來咱們?cè)谏芷诤瘮?shù)?attached
?中讀取一個(gè)用戶的登錄狀態(tài):
// components/authorization/index.js
Component({
data: {
isFlag: false,
},
// 生命周期函數(shù)
lifetimes: {
attached() {
// 登錄狀態(tài)
const isFlag= !!getApp().token
// 記錄登錄狀態(tài)
this.setData({ isFlag})
// 未登錄重定向到登錄頁
if (!isFlag) {
// 引導(dǎo)用戶到登錄頁面
wx.redirectTo({
url: `/pages/login/index`,
})
}
},
},
})
獲取頁面路徑
在用戶完成登錄后頁面要回到用戶原本要訪問的頁面,要實(shí)現(xiàn)這個(gè)功能需要咱們先獲取用戶正在訪問的頁面路徑,然后把這個(gè)路徑傳給登錄頁面,這樣在登錄成功后便可以再跳轉(zhuǎn)到回這個(gè)頁面了,獲取頁面路徑的方法如下:
// components/authorization/index.js
const app=getApp()
Component({
data: {
isFlag: false,
redirect:''
},
// 生命周期函數(shù)
lifetimes: {
attached() {
// 記錄登錄狀態(tài)
this.setData({
isFlag: app.token ? 'true' : "false"
})
// 如果未登錄重定向到登錄頁面 將當(dāng)前頁面的路徑存下來
if (!app.token) {
wx.redirectTo({
url: '/pages/login/index'
})
}
},
},
})
? ? 獲取當(dāng)前頁面的路徑,在未登陸的情況下通過地址參數(shù)傳給登錄頁面
完成登錄頁面的功能之后 登錄成功就可以根據(jù)保存的路徑跳轉(zhuǎn)到當(dāng)前頁面
// components/authorization/index.js
const app=getApp()
Component({
data: {
isFlag: false,
redirect:''
},
// 生命周期函數(shù)
lifetimes: {
attached() {
// 記錄登錄狀態(tài)
this.setData({
isFlag: app.token ? 'true' : "false"
})
// 讀取當(dāng)前歷史棧getCurrentPages() 第一個(gè)歷史頁面getCurrentPages()[0]
// console.log(getCurrentPages()[getCurrentPages().length-1].route,789); //最后一個(gè)歷史頁面
const redirect = getCurrentPages()[getCurrentPages().length - 1].route
console.log(redirect);
if (!app.token) {
wx.redirectTo({
//獲取當(dāng)前頁面的路徑,在未登陸的情況下通過地址參數(shù)傳給登錄頁面
url: '/pages/login/index?redirect=/' + redirect
})
this.setData({
redirect: redirect
})
},
},
})
在登錄頁面的onLoad 中拿到傳遞過來的歷史路徑 登錄成功跳回到歷史路徑文章來源:http://www.zghlxwxcb.cn/news/detail-498381.html
// 跳轉(zhuǎn)頁面 寫活:登錄成功就要跳回到上一個(gè)歷史頁面
wx.redirectTo({
// url: '/pages/index/index',
url: this.data.redirect || '/pages/my/index'
})
},
// 拿到歷史頁面路徑redirect
onLoad(option) {
console.log(option.redirect, 123456);
this.setData({
redirect: option.redirect
})
},
?登錄頁面整體邏輯如下文章來源地址http://www.zghlxwxcb.cn/news/detail-498381.html
登錄頁面login/index
const app=getApp()
Page({
data: {
countDownVisible: false, //
mobile: '13066668888',
code: '', //用戶輸入的驗(yàn)證碼 登錄請(qǐng)求的時(shí)候后端接口需要的是code
userCode: '', //通過手機(jī)號(hào)發(fā)請(qǐng)求拿到的code
redirect:'' //歷史頁面路徑
},
// 表單輸入事件 獲取輸入的手機(jī)號(hào)
InputHandle(e) {
console.log(e.detail, '獲取輸入的手機(jī)號(hào)');
this.setData({
mobile: e.detail
})
},
// 獲取輸入的驗(yàn)證碼
CodeHandle(e) {
console.log(e.detail, '獲取輸入的驗(yàn)證碼');
this.setData({
code:e.detail
})
},
// 點(diǎn)擊獲取驗(yàn)證碼
async start() {
//1 校驗(yàn)手機(jī)號(hào)是否合法 如果合法就發(fā)請(qǐng)求 發(fā)送驗(yàn)證碼
const reg = /^(0|86|17951)?(13[0-9]|15[012356789]|166|17[3678]|18[0-9]|14[57])[0-9]{8}$/
let flag = reg.test(this.data.mobile) //如果手機(jī)號(hào)不合法 返回false
if (!flag) {
wx.utils.toast('請(qǐng)輸入合法手機(jī)號(hào)')
}
// 發(fā)請(qǐng)求,獲取驗(yàn)證碼
const res = await wx.http.get('/code', {
mobile: this.data.mobile.trim()
})
this.setData({
countDownVisible: true,
userCode: res.data.code
})
console.log(res, 3333); //獲取的code
},
// 點(diǎn)擊登錄 跳轉(zhuǎn)到之前的歷史頁面
async loginHandle(){
// 拿到點(diǎn)擊獲取的隨機(jī)驗(yàn)證碼 與輸入的驗(yàn)證碼進(jìn)行校驗(yàn) 如果一致則登錄 否則提示驗(yàn)證碼錯(cuò)誤
if(this.data.code!==this.data.userCode) return wx.utils.toast('請(qǐng)輸入正確的驗(yàn)證碼')
// 如果是一致就發(fā)請(qǐng)求登錄
const res =await wx.http.post('/login',{
mobile:this.data.mobile,
code:this.data.code
})
console.log(res,44444); //可以拿到token 和 refreshToken 存在本地和app.js中 存在本地中是為了token持久化
app.token=res.data.token,
app.refreshToken=res.data.refreshToken,
wx.setStorage({
key:'token',
data:app.token
})
wx.setStorage({
key:'refreshToken',
data:app.refreshToken
})
// 跳轉(zhuǎn)頁面 寫活:登錄成功就要跳回到上一個(gè)歷史頁面
wx.redirectTo({
// url: '/pages/index/index',
url: this.data.redirect || '/pages/my/index'
})
},
// 拿到歷史頁面路徑redirect
onLoad(option) {
console.log(option.redirect, 123456);
this.setData({
redirect: option.redirect
})
},
// 獲取倒計(jì)時(shí)信息
countDownChange(ev) {
this.setData({
timeData: ev.detail,
countDownVisible: ev.detail.minutes === 1 || ev.detail.seconds > 0,
})
},
})
到了這里,關(guān)于微信小程序 實(shí)現(xiàn)導(dǎo)航守衛(wèi)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!