1. 程式人生 > >解決vue router元件狀態重新整理消失的問題

解決vue router元件狀態重新整理消失的問題

場景:vue-router實現的單頁應用,登入頁呼叫登入介面後,伺服器返回使用者資訊,然後通過router.push({name: ‘index’, params: res.data})跳轉到主頁,並在主頁顯示資料。但是當重新整理頁面時,由於並不是通過登入介面進入主頁,router中沒有‘params: res.data’資訊,主頁無法獲取到登入資訊。

解決方案:

1、session&伺服器渲染

傳統的方案是,登入頁和主頁是單獨的兩個頁面,登入成功後伺服器生成使用者資訊對應的session,然後渲染主頁資料,並通過響應頭將sessionid傳給瀏覽器並生成相應的cookie檔案。這樣下次請求頁面時,瀏覽器會在http header帶上相應的cookie,然後伺服器根據cookie中的sessionid判斷使用者是否登入,再顯示使用者資料。

如果專案採用前後端分離思想,伺服器只提供介面,不進行伺服器渲染,那麼這種辦法是行不通了。

2、$route.query

我們可以在路由跳轉的時候帶上登入請求的引數:

router.push({name:'index', query:{username: 'xxx', password: 'xxxxxx'}})
...
this.$ajax({
 url: 'xxx',
 method: 'post',
 data: {
 username: this.$route.query.username,
 password: this.$route.query.password
 }
})

這樣登入引數會被儲存在url中,像這樣:“ http://xxx.xxx.xxx/index?username=xxx&password=xxxxxx ”,然後在created鉤子中呼叫登入介面來返回資料。

即使密碼進行了加密,將使用者名稱密碼這類敏感資訊放在url中肯定也是不合理。

3、cookie

另一個辦法是把登入引數存入cookie,然後在created鉤子中獲取cookie中存的資訊,再呼叫登入介面。將使用者名稱密碼存入cookie中同樣不合理,改進版是登入成功後伺服器返回一個token,在有效期內通過token獲取使用者資料。

cookie存取資料比較麻煩,因為cookie是一個字串,儲存的鍵值對以 “=” 連結,需要額外寫操作cookie的方法。

function setCookie (name, value, exdays) {
 let date = new Date()
 date.setTime(date.getTime() + (exdays * 24 * 60 * 60 * 1000))
 let expires = 'expires=' + date.toGMTString()
 document.cookie = name + '=' + value + '; ' + expires
}
function getCookie (name) {
 name = name + '='
 let cookieArr = document.cookie.split(';')
 for (let i = 0; i < cookieArr.length; i++) {
 let cookie = cookieArr[i].trim()
 if (cookie.indexOf(name) === 0) {
  return cookie.slice(name.length)
 }
 }
 return ''
}

4、HTML5 Web儲存

提到Web儲存,潛意識肯定覺得很多瀏覽器都不支援,其實IE8及以上都支援localStorage和sessionStorage了。Vue專案最低支援IE9,所以可以放心的使用Web儲存。

localStorage儲存資料沒有時間限制,不主動刪除就不會失效。而sessionStorage是在頁面或者瀏覽器關閉時就會失效,適合本場景應用。

我們可以把token資訊存在sessionStorage中,然後每次重新整理頁面通過token請求資料;但是既然能夠把token儲存到本地,為什麼不直接把常用的資料直接儲存到本地呢?利用本地資料,可以減少客戶端網路請求,還可以降低伺服器負擔。

由於sessionStorage中儲存的值是字串,直接賦值非字串型別會先呼叫其toString()方法。例如執行sessionStorage.user = user,儲存的值卻是[object Object]。我們可以通過JSON.stringify()將需要儲存的物件轉為JSON字串再儲存到sessionStorage,然後在需要使用時通過JSON.parse()將字串轉回物件。

let user = {
 name: 'admin',
 address: 'xxx',
 email: '[email protected]'
}
// sessionStorage.user = user // [object Object]
sessionStorage.user = JSON.stringify(user)
...
let data = JSON.parse(sessionStorage.user)

最後

為了幫助大家讓學習變得輕鬆、高效,給大家免費分享一大批資料,幫助大家在成為全棧工程師,乃至架構師的路上披荊斬棘。在這裡給大家推薦一個前端全棧學習交流圈:866109386.歡迎大家進群交流討論,學習交流,共同進步。

當真正開始學習的時候難免不知道從哪入手,導致效率低下影響繼續學習的信心。

但最重要的是不知道哪些技術需要重點掌握,學習時頻繁踩坑,最終浪費大量時間,所以有有效資源還是很有必要的。

最後祝福所有遇到瓶疾且不知道怎麼辦的前端程式設計師們,祝福大家在往後的工作與面試中一切順利。