您好,登錄后才能下訂單哦!
小編給大家分享一下vue刷新頁面以后丟失store數據怎么辦,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
刷新頁面時vue實例重新加載,store就會被重置,可以把定義刷新前把store存入本地localStorage、sessionStorage、cookie中,localStorage是永久儲存,重新打開頁面時會讀取上一次打開的頁面數據,sessionStorage是儲存到關閉為止,cookie不適合存大量數據。根據我的需求,最合適的是sessionStorage。
beforeunload在頁面刷新時觸發,可以監聽這個方法,讓頁面在刷新前存store到sessionStorage中。
當然,在頁面刷新時還要讀取sessionStorage中的數據到store中,讀取和儲存都寫在app.vue中。
export default { name: 'app', created () { // 在頁面加載時讀取sessionStorage if (sessionStorage.getItem('store')) { this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('store')))) } // 在頁面刷新時將store保存到sessionStorage里 window.addEventListener('beforeunload', () => { sessionStorage.setItem('store', JSON.stringify(this.$store.state)) }) } }
補充知識:vue項目將token存在(vuex)store和localstorage中
一、準備工作和token
1、準備工作
了解(session,cookie)token
Token的引入:Token是在客戶端頻繁向服務端請求數據,服務端頻繁的去數據庫查詢用戶名和密碼并進行對比,判斷用戶名和密碼正確與否,并作出相應提示,在這樣的背景下,Token便應運而生。
token 是在服務端產生的一串字符串,以作客戶端進行請求的一個令牌。如果前端使用用戶名/密碼向服務端請求認證,服務端認證成功,那么在服務端會返回 Token 給前端。前端可以在每次請求的時候帶上 Token 證明自己的合法地位。如果這個 Token 在服務端持久化(比如存入數據庫),那它就是一個永久的身份令牌(除非設置了有效期)。
token 優點
Token 完全由應用管理,所以它可以避開同源策略
Token 可以避免 CSRF 攻擊
Token 可以是無狀態的,可以在多個服務間共享
減輕服務器的壓力,減少頻繁的查詢數據庫,使服務器更加健壯。
安裝vuex
cnpm install vuex --save
2、介紹token用法
在前后端完全分離的情況下,Vue項目中實現token驗證大致思路如下:
1、第一次登錄的時候,前端調后端的登陸接口,發送用戶名和密碼
2、后端收到請求,驗證用戶名和密碼,驗證成功,就給前端返回一個token
3、前端拿到token,將token存儲到localStorage和vuex中,并跳轉路由頁面
4、前端每次跳轉路由,就判斷 localStroage 中有無 token ,沒有就跳轉到登錄頁面,有則跳轉到對應路由頁面
5、每次調后端接口,都要在請求頭中加token
6、后端判斷請求頭中有無token,有token,就拿到token并驗證token,驗證成功就返回數據,驗證失敗(例如:token過期)就返回401,請求頭中沒有token也返回401
7、如果前端拿到狀態碼為401,就清除token信息并跳轉到登錄頁面
二、創建storage,store,request
1、src目錄:
注:創建storage是可選的,因為我把localstorage(緩存)封裝到了storage.js(本文后續代碼均是用自己封裝的js);創建store是必須的!
2、創建storage(可選)
// 封裝操作localstorage本地存儲的方法 模塊化 var storage = { set(key, value) { localStorage.setItem(key, JSON.stringify(value)); // localStorage.key = value; // localStorage[key] = value; }, get(key) { return JSON.parse(localStorage.getItem(key)); }, getForIndex(index) { return localStorage.key(index); }, getKeys(){ let items = this.getAll(); let keys = []; for (let index=0;index<items.length;index++){ keys.push(items[index].key); } return keys; }, getLength() { return localStorage.length; }, getSupport() { return (typeof (Storage) !== "undefined") ? true : false; }, remove(key) { localStorage.removeItem(key); }, removeAll() { localStorage.clear(); }, getAll() { let len = localStorage.length; // 獲取長度 let arr = new Array(); // 定義數據集 for (var i = 0; i < len; i++) { // 獲取key 索引從0開始 var getKey = localStorage.key(i); // 獲取key對應的值 var getVal = localStorage.getItem(getKey); // 放進數組 arr[i] = { 'key': getKey, 'val': getVal, } } return arr; } } export default storage;
3、創建store
import Vue from 'vue' import Vuex from 'vuex' import storage from '@/model/storage' Vue.use(Vuex); // 用Vuex.Store對象用來記錄token const store = new Vuex.Store({ state: { // 存儲token // token: storage.get('token') ? storage.get('token') : '', token:"", userName:"" // 可選 }, actions: { // removeToken: () => { // context.commit('set_token') // } }, // 計算屬性 mutations: { // 修改token,并將token存入localStorage set_token(state,token) { state.token = token; storage.set('token', token); console.log('store、localstorage保存token成功!'); }, del_token(state) { state.token = ""; storage.remove("token"); }, // 可選 setUserInfo(state, userName) { state.userName = userName; } } }); export default store;
4、創建request
import axios from 'axios' import store from '@/store' import router from '@/router' // create an axios instance const service = axios.create({ // index.js設置了代理(解決跨域) invoice = http://58.246.79.142:25005 baseURL: "/invoice", // url = base url + request url timeout: 5000, // request timeout } }) //添加請求攔截器,若token存在則在請求頭中加token,不存在也繼續請求 service.interceptors.request.use( config => { // 每次發送請求之前檢測都vuex存有token,那么都要放在請求頭發送給服務器,沒有則不帶token // Authorization是必須的 if (store.state.token) { config.headers.Authorization = store.state.token; } return config; }, error => { console.log("在request攔截器顯示錯誤:", error.response) return Promise.reject(error); } ); //respone攔截器 service.interceptors.response.use( response => { // 在status正確的情況下,code不正確則返回對應的錯誤信息(后臺自定義為200是正確,并且將錯誤信息寫在message),正確則返回響應 return response.data.code == 200 ? response : Promise.reject(response.data.message); }, error => { // 在status不正確的情況下,判別status狀態碼給出對應響應 if (error.response) { console.log("在respone攔截器顯示錯誤:", error.response) switch (error.response.status) { case 401: //可能是token過期,清除它 // this.$store.commit("del_token"); store.commit("del_token"); router.replace({ //跳轉到登錄頁面 path: '/login', // 將跳轉的路由path作為參數,登錄成功后跳轉到該路由 query: { redirect: router.currentRoute.fullPath } }); } } return Promise.reject(error.response.data); } ); export default service
三、配置代理,封裝路由router、設置路由守衛,在main.js中引入router
一、配置代理
二、封裝路由router,并設置路由守衛
/* eslint-disable */ import Vue from 'vue' import Router from 'vue-router' import Main from '@/main/index' import store from '@/store' import storage from '@/model/storage' Vue.use(Router) const routes = [ { path: '/', name: 'Main', redirect: '/login', // 某些頁面規定必須登錄后才能查看 ,可以在router中配置meta,將需要登錄的requireAuth設為true, meta: { requireAuth: true, } }, { path: '/login', component: () => import('@/views/login'), }, { path: '/invoice', redirect: '/invoice', component: Main, }, ] }, { path: '*', component: Main } ] const router = new Router({ routes: routes }) // 設置路由守衛,在進頁面之前,判斷有token,才進入頁面,否則返回登錄頁面 if (storage.get("token")) { store.commit("set_token", storage.get("token")); } router.beforeEach((to, from, next) => { // 判斷要去的路由有沒有requiresAuth // to.matched.some(r => r.meta.requireAuth) or to.meta.requiresAuth if (to.matched.some(r => r.meta.requireAuth)) { if (store.state.token) { next(); //有token,進行request請求,后臺還會驗證token } else { next({ path: "/login", // 將剛剛要去的路由path(卻無權限)作為參數,方便登錄成功后直接跳轉到該路由,這要進一步在登陸頁面判斷 query: { redirect: to.fullPath } }); } } else { next(); //如果無需token,那么隨它去吧 } }); export default router
三、在main.js中引入router
import Vue from 'vue' // import Vuex from 'vuex' import App from './App' import router from './router' import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css' // import VueResource from 'vue-resource' // import axios from 'axios' // 兼容ie // import 'babel-polyfill'; Vue.use(ElementUI); // Vue.use(Vuex); // Vue.use(VueResource); // Vue.use(axios); Vue.config.productionTip = false Vue.component(CollapseTransition.name, CollapseTransition) // this.$ajax 全局使用axios // Vue.prototype.$ajax=axios; new Vue({ el: '#app', router:router, components: { App }, template: '<App/>' })
四、登錄頁面實際使用
只給出表單提交示例函數和依賴js
import { postLogin } from "@/api/login"; submitForm(formName) { this.$refs[formName].validate(valid => { if (valid) { let that = this; // console.log('username',this.loginForm.username) // 通過校驗規則后進入校驗用戶名密碼是否正確 postLogin(this.loginForm.username, this.loginForm.password) .then(res => { console.log(res); that.$store.commit("set_token", res.data.token); that.$store.commit("setUserInfo", res.data.account); this.$notify({ title: "登錄成功", type: "success", showClose: false, duration: 1000 }); setTimeout(() => { // 此時要判斷/login后面的參數,若無參數,進入主頁; this.$router.push("/index"); // 若有參數則參數為未有權限的那個路由,跳轉到那個路由 // this.$router.push(***); -- 具體要自己在這實現 }, 1000); }) .catch(error => { // 錯誤分為 status-請求錯誤 和 code-賬號密碼錯誤 this.$message.error(error); console.log(error); }); } else { // 不符合前端校驗 this.$message.error('format error:'+error); console.log('format error:',error); return false; } }); }
上面依賴的@/api/login:
import request from '@/utils/request.js' export function postLogin(account,password) { console.log(account,password) return request({ url: '/login', method: 'post', params:{ // 具體傳參(鍵)要看后臺要求 account:account, password:password } }) }
以上是vue刷新頁面以后丟失store數據怎么辦的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。