摘要:接上篇議題合理的架構討論上傳送門。處理思路如下使用上面定義的方法獲取如果能獲取到則說明有有效的,則時候即可跳轉到目標頁如果獲取到空字符串,則說明無效或不存在,跳轉至登錄頁面。
接上篇《【Geek議題】合理的VueSPA架構討論(上)》傳送門。
自動化維護登錄狀態登錄狀態標識符跟token類似,都是需要自動維護有效期,但也有些許不同,獲取過程只在用戶登錄或注冊的時候,不需要自動獲取。
本人比較推薦使用公共狀態管理vuex進行自動化管理,并配合路由鉤子,減少代碼編寫時的顧慮。
示例中公共狀態管理中的user模塊里定義了userIdObj,其中包含了userId登錄狀態標識符和過期時間。
維護userId是否過期主要是通過vuex中的getter來實現。
const getters = { getUserId: (_state) => { // 獲取公共狀態中的userIdObj const userIdObj = { ..._state.userIdObj, }; // 是否過期標識 let isExpire = false; // 判斷是否過期 if (userIdObj && userIdObj.userId) { isExpire = new Date().getTime() - userIdObj.expireTime > -10000; } // 如果過期則返回空字符串(不一定) if (!userIdObj || !userIdObj.userId || isExpire) { return ""; } // 沒過期則返回userId return userIdObj.userId; }, };路由鉤子中處理userId
回顧上篇中全局的路由鉤子router.beforeEach,當目標路由元信息requiresAuth為true則表示,這個路由必須有登錄狀態才能訪問,這時候就會進行登錄狀態檢查。處理思路如下:
使用上面定義的getter方法獲取userId;
如果能獲取到則說明有有效的userId,則時候即可跳轉到目標頁;
如果獲取到空字符串,則說明userId無效或userId不存在,跳轉至登錄頁面。
【PS】示例這里的處理還不完美,最好跳轉登錄前保存好目標路由,登錄成功就直接跳轉去該路由。
router.beforeEach((to, from, next) => { // ... // 檢查登錄狀態 if (to.meta.requiresAuth) { console.log("目標路由需要登錄狀態"); if (!store.getters.getUserId) { console.log("內存無登錄信息,嘗試在本地存儲中找"); const localUserIdObj = JSON.parse(localStorage.getItem("userIdObj")); if (localUserIdObj) { // 如果本地存儲中有userIdObj,則提交到公共狀態 store.commit("setUserIdObj", localUserIdObj); } } // 再次檢查公共狀態里有沒有userId if (!store.getters.getUserId) { console.log("依舊無登錄信息"); router.push({ name: "userLogin", }); } } next(); });”頁面”中獲取登錄狀態
在“頁面”中獲取userId也很簡單,使用計算屬性是最好的,返回的userId具有響應性,這做的好處也是為了實時將登錄狀態反應到頁面上,才不會出現顯示已登錄,但用戶刷新一下才能知道登錄狀態已過期的尷尬情況。
【PS】一些需要用戶登錄狀態的api函數,也是通過這樣的方法獲取并使用。當然,建議在非首屏加載使用的api函數(比如提交表單),需要在調用前,檢查一下userId還存不存在,以免出錯。
computed: { // 獲取登錄狀態 userId() { return this.$store.getters.getUserId; }, },使用公共狀態管理維護連接
有時會有需要取消請求的需求,比如上傳文件耗時過長,用戶不想等,這時候就必須有取消的功能。
上篇提到的axios已經提供了一個基于CancelToken的取消機制,這里我們要配合vuex實現對全局連接的實時監控。
【PS】示例的接口名稱都是在寫api函數的時候定義好的,想要更加靈活,可以每次請求都多帶帶指定名字。公共狀態管理配置
示例中給公共狀態下的com模塊添加了cancelToken數組,用來保存發起的連接的名稱和source(取消標記),并提供了如下三個mutations方法
// 增加cancelToken addCancelToken(_state, cancelToken) { _state.cancelToken.push(cancelToken); const arr = _state.cancelToken; _state.cancelToken = arr; }, // 刪除指定名字的cancelToken deleteCancelToken(_state, name) { _state.cancelToken.some((i, index) => { if (i.name === name) { _state.cancelToken.splice(index, 1); return true; } return false; }); }, // 清空cancelToken clearCancelToken(_state) { _state.cancelToken.forEach((i) => { if (i.source && typeof i.source.cancel === "function") { i.source.cancel(`cancel${name}`); } }); _state.cancelToken = []; },請求攔截器配置
基本思路:
在“請求發起前攔截器”中獲取到source(取消標記),寫入請求配置,并提交名稱和source到公共狀態管理;
這時候通過查詢公共狀態中是否有這個名字的連接就可以獲取到source進行取消;
在“響應攔截器”中我們將已經成功的請求在公共狀態管理中移除。
// 請求發起前攔截器 myAxios.interceptors.request.use((_config) => { const config = _config; const source = axios.CancelToken.source(); // 獲取cancelToken config.cancelToken = source.token; // 取消請求標記保存 store.commit("addCancelToken", { name: config.name, source, }); return config; }, () => { // 異常處理 console.error("請求發起前攔截器異常"); }); // 響應攔截器 myAxios.interceptors.response.use((response) => { // 刪除取消標記 store.commit("deleteCancelToken", response.config.name); console.log(response); return response; }, (error) => { console.error(error); // 清理取消標記 store.commit("clearCancelToken"); return Promise.reject(error); });代碼中使用
使用計算屬性獲取cancelToken數組,這里是響應式的,所有我們其實可以知道現在有多少個請求還未完成了。
【PS】實時對全局請求的監控已經實現,其實可以做的擴展就很多了,比如可以全局化loading的顯示,只要數組內一直不為空持續一段時間就可以判斷需要顯示loading,如果為空則關閉loading。
computed: { // 獲取連接列表 cancelToken() { return this.$store.state.com.cancelToken; }, },
遍歷這個數組,查找到對應名字的連接就可以取消了。
this.cancelToken.forEach((i) => { console.log(i); if (i.name === "上傳文件" && typeof i.source.cancel === "function") { console.log("取消上傳"); i.source.cancel(`cancel${name}`); } });其他細節技巧 掛載常用工具到vue原型上減少引用
在初始化Vue的根組件前,給Vue的原型鏈上添加常用的工具,可以方便在vue文件中使用。這樣做會影響所有Vue示例推薦只在單頁面應用中使用。
比如下面以我們的api集為例,這樣在vue文件中this.$api就可以使用我們的api集,不需要重復引用。
// 將api模塊掛載進vue方便在this調用 Vue.prototype.$api = api;批量導入過濾器
在util文件夾下可以新建一個專門用來存過濾器的filter.js,然后批量導入的全局過濾器中。
import * as filters from "./util/filter"; Object.keys(filters).forEach(k => Vue.filter(k, filters[k]));
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/52120.html
摘要:接上篇議題合理的架構討論上傳送門。處理思路如下使用上面定義的方法獲取如果能獲取到則說明有有效的,則時候即可跳轉到目標頁如果獲取到空字符串,則說明無效或不存在,跳轉至登錄頁面。 接上篇《【Geek議題】合理的VueSPA架構討論(上)》傳送門。 自動化維護登錄狀態 登錄狀態標識符跟token類似,都是需要自動維護有效期,但也有些許不同,獲取過程只在用戶登錄或注冊的時候,不需要自動獲取。 ...
摘要:下面也是以模塊的模塊集為例,可以發現和路由有一些不同就是這里為了防止模塊跟全局耦合,運用函數式編程思想類似于依賴注入,將全局的實例作為函數參數傳入,再返回出一個包含的對象,這個導出的對象將會被以模塊名命名,合并到全局的集中。 前言 web前端發展到現代,已經不再是嚴格意義上的后端MVC的V層,它越來越向類似客戶端開發的方向發展,已獨立擁有了自己的MVVM設計模型。前后端的分離也使前端人...
摘要:下面也是以模塊的模塊集為例,可以發現和路由有一些不同就是這里為了防止模塊跟全局耦合,運用函數式編程思想類似于依賴注入,將全局的實例作為函數參數傳入,再返回出一個包含的對象,這個導出的對象將會被以模塊名命名,合并到全局的集中。 前言 web前端發展到現代,已經不再是嚴格意義上的后端MVC的V層,它越來越向類似客戶端開發的方向發展,已獨立擁有了自己的MVVM設計模型。前后端的分離也使前端人...
摘要:同源策略年,同源政策由公司引入瀏覽器。標簽不受同源策略限制,但只能發起請求。這一行為使得不同域的特定文檔可以讀取該屬性值,因此可以繞過同源策略并使跨域消息通信成為可能。 前言 現在cross-origin resource sharing(跨域資源共享,下簡稱CORS)已經十分普及,算上IE8的不標準兼容(XDomainRequest),各大瀏覽器基本都已支持,當年為了前后端分離、if...
摘要:同源策略年,同源政策由公司引入瀏覽器。標簽不受同源策略限制,但只能發起請求。這一行為使得不同域的特定文檔可以讀取該屬性值,因此可以繞過同源策略并使跨域消息通信成為可能。 前言 現在cross-origin resource sharing(跨域資源共享,下簡稱CORS)已經十分普及,算上IE8的不標準兼容(XDomainRequest),各大瀏覽器基本都已支持,當年為了前后端分離、if...
閱讀 2078·2021-11-23 10:13
閱讀 2788·2021-11-09 09:47
閱讀 2737·2021-09-22 15:08
閱讀 3312·2021-09-03 10:46
閱讀 2230·2019-08-30 15:54
閱讀 909·2019-08-28 18:09
閱讀 2429·2019-08-26 18:26
閱讀 2341·2019-08-26 13:48