1. Problem Description:
Generally, when the login is successful, the user information and menu information need to be placed in vuex as global shared data. However, when the page is refreshed, the data in vuex will be reinitialized, resulting in data loss. Because the data in vuex is saved in the running memory, when the page is refreshed, the page will reload the vue instance, and the data in vuex will be re assigned.
2. Solution:
Method 1: save the data in vuex directly to the browser cache (sessionStorage, localStorage, cookie)
Method 2: when the page is refreshed, request the remote data again to dynamically update vuex data
Method 3: request remote data from the parent page to the background, and save vuex data to sessionStorage before page refresh (in case the amount of requested data is too large, and the returned data cannot be obtained when the page is loaded)
analysis:
The disadvantage of method 1 is that it is unsafe and not suitable for the storage of large amounts of data;
Method 2 applies to a small amount of data without network delay;
Method 3 is the key point, and method 2 is used together with method 1.
3. Solving process: @ 1
3.1. Select appropriate browser storage
localStorage -- it is permanently stored locally unless you take the initiative to delete it;
sessionStorage -- it is stored until the current page is closed and is not associated with other tab pages;
Cookies are stored according to the effective time you set, but the disadvantage is that they cannot store big data and are not easy to read, and will interact with the background.
sessionStorage is selected in this method because vue is a single page application, and all operations jump routes on one page. Another reason is that sessionStorage can ensure that the data of sessionStorage is empty when the page is opened. If it is localStorage, the data of the last page opened will be read.
3.2 solution
Because the data in the state is responsive, the sessionStorage storage also changes, and the values in the state can only be changed through changes.
First, after the user logs in successfully, then the user information and menu information are distributed and saved to vuex through actions. Then calculate the menu data of state in vuex on the menu page, parse and assemble the data into the format required by the front-end components, and then render the components to generate the menu tree. If the page is not refreshed, everything is normal.
After successful login, synchronize user and menu data to vuex
Listen for menu data in vuex on the menu page
Solution for page refresh:
When the page is refreshed, the background data is requested asynchronously, and then the data in vuex is updated dynamically. One of the problems is the network delay and large amount of data. At this time, the page has been loaded before vuex gets the data returned from the background, which will cause data loss. Therefore, the solution is to listen to the events before browser refresh and save the data in vuex to sessionStorage before browser refresh. After successful refresh, if the data requested asynchronously has not been returned, directly obtain the data in sessionStorage, otherwise obtain the data in vuex. (the background data will be retrieved from sessionStorage only if it has not been retrieved after refresh. To ensure the security of the data, even if the data in sessionStorage is obtained, it is safe, because each refresh will re assign the value, so there is no need to worry about the data being tampered with. Secondly, the data in sessionStorage is encrypted.)
When the parent page requests data from the background and listens for events before browser refresh, save vuex data to sessionStorage
Request data from the background on the parent page and distribute the returned data to vuex
3. Solution process: @2 vuex persistedstate
Principle:
Save the state of vuex in localStorage or sessionStorage or a cookie
At the moment of refreshing the page, the vuex data disappears, and vuex will go to sessionStorage to get the data back. In a disguised way, the data refresh is not lost~
usage method:
Installation: NPM install vuex persistedstate -- save
Index. Under store JS, import and configure
import createPersistedState from "vuex-persistedstate" const store = new Vuex.Store({ // ... plugins: [createPersistedState()] })
At this time, you can select the location of data storage, which can be localStorage/sessionStorage/cookie. Here, take the storage to sessionStorage as an example, and the configuration is as follows:
import createPersistedState from "vuex-persistedstate" const store = new Vuex.Store({ // ... plugins: [createPersistedState({ storage: window.sessionStorage })] })
Store the specified state:
Vuex persisted state persists all States by default. Specify the States to be persisted. The configuration is as follows:
import createPersistedState from "vuex-persistedstate" const store = new Vuex.Store({ // ... plugins: [createPersistedState({ storage: window.sessionStorage, reducer(val) { return { //Only user s in state are stored user: val.user } } })]
At this moment, val corresponds to the contents stored in several js files under the store/modules folder, that is, several modules import ed in the stor/index. You can print and see them yourself. You can configure the name of the data here to store the data permanently. At present, I only want to persist the data of the storage module.
Note: if you want to configure multiple options now, write plugins as a one-dimensional array, otherwise an error will be reported.
import createPersistedState from "vuex-persistedstate" import createLogger from 'vuex/dist/logger' //Judgment environment}vuex prompt: not used in production environment const debug = process.env.NODE_ENV !== 'production' const createPersisted = createPersistedState({ storage: window.sessionStorage }) export default new Vuex.Store({ // ... plugins: debug ? [createLogger(), createPersisted] : [createPersisted] })
3. Solution process: @3 vuex along
Save a copy of the data in the state to local storage (localStorage, sessionStorage, cookie)
//App.vue
<script> export default{ created() { //Read the status information in sessionStorage when the page is loaded if (sessionStorage.getItem("store") ) { this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(sessionStorage.getItem("store")))) } //Save the information in vuex to sessionStorage when the page is refreshed window.addEventListener("beforeunload",()=>{ sessionStorage.setItem("store",JSON.stringify(this.$store.state)) }) } } </script>
2. Use third-party plug-ins such as vuex along (in essence, it is cached locally using session, etc.)
import Vue from 'vue' import Vuex from 'vuex' import VueXAlong from 'vuex-along' Vue.use(Vuex) let productData = require('@/assets/api/list.json') const moduleA = { state: { a1: 'a1', a2: 'a2', } } export default new Vuex.Store({ state: { productList: [],//List data cartList: [],//Shopping cart data }, mutations: { //Product list setProductList(state, data){ state.productList = data }, //add to cart setCartList(state, id){ let cartIndex = state.cartList.findIndex(item => item.id === id) if(cartIndex < 0){ state.cartList.push({id, count: 1}) }else{ state.cartList[cartIndex].count++ } }, //Delete cart item deleteCartList(state, id){ let cartIndex = state.cartList.findIndex(item => item.id === id) state.cartList.splice(cartIndex, 1) }, //Edit cart item quantity editCartList(state, data){ let cartIndex = state.cartList.findIndex(item => item.id === data.id) state.cartList[cartIndex].count = data.count }, clearCart(state){ state.cartList = [] }, }, actions: { getProductList(context){ //Simulate the ajax request and store the returned information directly in the store setTimeout(()=>{ context.commit('setProductList', productData) }, 2000) }, buy(context){ //Simulate an ajax request and return the result to the place where the operation is submitted by returning the promise object return new Promise((resolve, reject) => { setTimeout(()=>{ context.commit('clearCart') resolve({msg:'checkout success ', code: 200}) //reject({message: 'Submit failed', code: 300}) }, 1000) }) } }, modules: { ma: moduleA }, //Cache state data to storage plugins: [VueXAlong()], //Full parameter configuration (sessionStorage data recovery priority is higher than localStorage) /* plugins: [VueXAlong({ // Set the saved collection name to avoid multi project data conflict under the same site name: 'my-app-VueXAlong', //Filter ma the data and store other data in localStorage local: { list: ['ma'],//Attribute name or module name to listen to isFilter: true,//Filter instead of save }, //Save ma's a1 data to sessionStorage session: { list: ['ma.a1'], isFilter: false, }, //Save using sessionStorage only //justSession: true, })] */ })