登錄/注冊
- 持久存儲用戶信息
- 問題
- 退出登錄
- 導航守衛
- 解決問題
持久存儲用戶信息
- 本地存儲:(在actions中請求成功時)
添加localStorage.setItem('token',result.data.token);
- 獲取存儲:(在user倉庫中,state中token初始值設為
localStorage.getItem('token')
)首先當本地存儲沒有值為null,倉庫中token初始值也為null
一旦登錄派發action,那么本地存儲就會有值,而此時倉庫的token也是有相同值
那么當一刷新,倉庫數據token會首先找到本地存儲的token值作為初始值
問題
- 跳轉到其他組件search時,Header又變成未登錄狀態
-
原因:
因為只是在home組件中派發了action,search組件并未派發,那么就獲取不到用戶信息 -
解決:
- 在所有組件添加上?不夠好。
- 放在App組件只執行一次?不行,
app一掛載就執行派發任務,但是還沒登錄呢,自然是獲取不到的,可是即便是登陸完了也是獲取不到,app早就掛載完了。只能第二次打開頁面才會呈現已登錄狀態。
- 用戶登錄完,還能再次進入login路由組件進行登錄嗎?不應該
退出登錄
- 業務
1. 需要發請求,通知服務器退出登錄【清除token數據】
2. 清除項目用到的數據【userInfo,token】
- api+vuex
//actions
async userLogout({ commit },) {//向服務器發送一次請求,清除服務器的tokenlet result = await reqLogout();if (result.code == 200) {//清除state數據---提交給mutaions//注意:actions里面不能處理statecommit('CLEAR');return 'ok';}else{return Promise.reject(new Error('fail'));}}//mutaions
CLAER(state){state.token = '';state.userInfo = {};//清除本地存儲tokenlocalStorage.removeItem('token');
}
- 派發action
退出登錄綁定@click="logout"
//method
async logout(){try{await this.$store.dispatch('userLogout');//跳轉到首頁this.$router.push('/home');}catch(error){alert(error.message);}
}
問題如果在search組件頁面中點擊退出登錄,路由應該跳轉到首頁。所有actions中需要返回成功與失敗結果,判斷是否跳轉
導航守衛
-
導航守衛:
是 Vue Router 提供的一種機制,主要用于在路由導航過程中進行控制和管理。它允許你在路由發生變化時執行一些操作,如權限驗證、數據預加載、頁面訪問控制等。 -
導航守衛的三種類型:
1. 全局守衛:只要路由發生變化,守衛就能監聽到并且攔截住
(1)router.beforeEach
- 全局前置守衛
(2)router.beforeResolve
- 全局解析守衛
(3)router.afterEach
- 全局后置鉤子
2. 路由獨享守衛
3. 組件內守衛 -
全局守衛
router.beforeEach((to,from,next)=>{})
:- to:跳轉的目的路由信息(如下圖
- from:當前路由信息(從哪個路由跳轉的)
- next:放行函數
- next():直接放行
- next(‘/login’):放行到指定路由
- next(false)
- to:跳轉的目的路由信息(如下圖
解決問題
- 用戶登錄了,不能在進入login
- 路由跳轉其他頁面同樣需要用戶信息展示
判斷倉庫中是否拿到token,如果有則說明登錄了
在router配置中
//引入store
import store from '@/store';
const router = new VueRouter({……});//全局路由守衛
router.beforeEach(async (from,to,next)=>{let token = store.user.token;if(token){//登錄成功//判斷如果to是login則不允許放行,register也同樣不允許if(to.path=='/login' || to.path=='/register'){//停留在home首頁next('/home');}else{//登錄成功,但跳轉的不是login//【home\search\detail……】//這里可以派發actions,獲取用戶信息//判斷有沒有獲取用戶信息if(name){//已經有用戶信息了next();}else{//沒有try{await store.dispatch('getUserInfo');next();}catch(error){alert(error.message);//token無效,跳到登錄頁再次登錄//發送請求userLogout清除服務器token(清除用戶信息和本地存儲token的業務mutaions也一并完成了)await store.dispatch('userLogout');next('/login');}}}}else{//未登錄后期再解決,還需開發別的頁面next();}
})
① 路由守衛關注有沒有token(有沒有登錄),有沒有獲取信息(派發getUserInfo)
② 請求不到用戶信息,說明token無效(過期了),則清除token,跳到登錄頁,重新登錄
③ 沒有token,一定沒有用戶信息;有用戶信息則放行所有