vue 页面刷新数据丢失、数据重置、数据缓存、data缓存、vuex缓存

页面刷新数据丢失

在vue中data、vuex store等都数据都是在内存当中的,页面一旦刷新,这些数据就会丢失(或者说被重置为初始值),在某些时候很影响用户体验。

缓存,恢复

要想使数据刷新不丢失,就得监听页面刷新事件,在刷新前将数据缓存到本地存储,页面刷新后再将数据从本地存储恢复。目前较普遍的做法是类似这样:

//App.vue的created():
 created() {
    //在页面加载从本地读取状态数据并写入vuex
    if (sessionStorage.getItem("store")) {
      this.$store.replaceState(
        Object.assign(
          {},
          this.$store.state,
          JSON.parse(sessionStorage.getItem("store"))
        )
      );
    }

    //页面刷新前将vuex里的状态数据保存到sessionStorage
    window.addEventListener(
    	"beforeunload",()=>{
    	sessionStorage.setItem("store",JSON.stringify(this.$store.state));
    });
  }

这样做是直接将一整个store保存到本地,但是很多时候我们需要保存到本地的只是一些关键性数据,这样做缺少灵活性,而且对于那些并不想放在vuex中的数据极不友好。

改进:dataCache.ts

基于上面将数据缓存到本地存储然后页面加载时恢复的思想,我对上面的方法做了一些改进:


let caches: Record<string, { [index: string]: unknown }> = {};

let isFirst = false;
let baseId = 0;

const generateId = () => baseId++;

export default {
    /**
     * 将data注册进缓存,可指定自定义的id(通常不推荐这样做),可指定需要进行缓存的属性
     * @param data 需要注册的数据对象
     * @param id 为需要注册的数据对象的id,id最好不要是纯数字,并且必须保证id的唯一性
     * @param propertyKeys 指定需要将data的哪些属性进行缓存
     */
    register(data: { [index: string]: unknown }, id?: string, ...propertyKeys: PropertyKey[]): number | string {
        if (id === undefined) {
            id = (generateId()).toString();
        } else {
            const nid = Number(id);
            //字符串的值为数字,为了防止与默认的id生成策略冲突,将其转化成 id+'_'+generateId() 的形式
            if (!isNaN(nid)) {
                id += '_' + generateId();
            }
        }

        const hasId = Reflect.has(caches, id);

        //第一次渲染就id就已经存在,说明提供了重复的id
        if (isFirst && hasId) {
            throw new Error('Duplicate id:\'' + id + '\'');
        }
        //不是首次渲染且id存在,则对data执行属性值的注入 
        else if (hasId) {
            const cache = Reflect.get(caches, id as PropertyKey);

            if (cache instanceof Array) {
                for (let i = 0; i < cache.length; i++) {
                    data[i] = cache[i];
                }
            } else {
                const keys = propertyKeys.length < 1 ? Reflect.ownKeys(cache) : propertyKeys;

                for (const key of keys) {
                    Reflect.set(data, key, Reflect.get(cache, key));
                }
            }
        }

        //将data放进缓存区
        Reflect.set(caches, id, data);

        return id;
    },
    /**
     * 初始化data-caches,在App.vue的created钩子中调用此函数即可
     * @param itemKey 在sessionStorage中存取caches时的key
     */
    init(itemKey: string): void {
        // 页面加载时读取sessionStorage中的数据
        const jsonString = sessionStorage.getItem(itemKey);

        // jsonString为null说明是第一次渲染页面
        if (jsonString === null) {
            isFirst = true;
        } else {
            caches = JSON.parse(jsonString);
        }

        // 监听页面刷新,刷新时将数据保存到sessionStorage
        window.addEventListener("beforeunload", () => {
            sessionStorage.setItem(itemKey, JSON.stringify(caches));
        });
    }
}

用法

第一步:初始化

将上述代码保存到一个文件名为 dataSessionCache.js 的文件里,
然后在App.vue的created钩子中调用 init 函数进行初始化,需要提供一个itemName:

	//App.vue
	import dc from "./ts/dataCache";

    export default {
        created() {
        	/*参数 itemKey 将作为 sessionStorage 进行
        	 getItem、setItem 操作时的 key,需要保证其唯一性.*/
            dc.init('data-caches');
        },
        //others
        ......
    };

第二步:注册

对于vue组件中的数据

对于vue组件中的数据例如data,将需要缓存的数据写到一个对象里面,然后再created钩子中进行注册,例如:

 import dc from "@/js/dataCache.ts";

 export default {
	data: () => ({	
		//need cache
		cached: {
        	num : 134,
        	str: 'str'
        	......
        }
        //other needn't cache
        ......
    }),

	created(){
		//第二个参数是待缓存的数据对象,必须是一个对象或者数组
		sc.register(this.$data.cached);
	}
 };
对于VueX store

对于vuex store中的数据也可以用类似的方法:

//store中:
export default new Vuex.Store({
    state: {
        cached: {
            key: 'data'
        }
        //others
        ......
    },
    //others
    ......
})

//App.vue中
import dsc from "@/js/dataCache.ts";

export default {
	created() {
    	//别忘了init
       dsc.init('data-caches');
       //注册
       dsc.register(this.$store.state.cached);
    },
    //others
    ......
};

缓存对象的非全部属性

register的原型是register(id, obj, ...propertyKeys),第三个参数的作用是指定需要进行缓存的属性,如果propertyKeys为空则会缓存其全部属性。例如,当我们想 在不改变原有代码的情况下 缓存一个单文本组件的部分data时,可以这样写:

export default {
	data: () => ({
            a:1,
            b:'b'
        }),
        
	created() {
		//只缓存属性a
    	dsc.register('this.data,undefined,'a');
    },
    //others
    ......
}

好处

  1. 在页面刷新前后进行数据的保存/恢复工作,性能开销少
  2. 对原有代码仅需少量修改,或者根本不需要修改原有代码
  3. 简单易用,灵活方便,初始化、注册两步就OK,并且可以灵活的指定需要缓存的数据

git仓库

https://gitee.com/szw-yunie/data-session-cache.js

### 回答1: 在 Vuex 中,您可以使用本地存储(例如 localStorage)来缓存状态数据,并在页面刷新时将其加载回状态中。 首先,您需要在 Vuex 的 store 实例中定义一个方法,用于在页面刷新时从本地存储中加载数据: ``` const store = new Vuex.Store({ state: { count: 0 }, mutations: { increment (state) { state.count++ } }, actions: { loadData ({ commit }) { const data = window.localStorage.getItem('vuex-data') if (data) { commit('increment', JSON.parse(data).count) } } } }) ``` 然后,您可以在 Vue 应用的 created 钩子函数中调用这个方法: ``` new Vue({ el: '#app', store, created () { this.$store.dispatch('loadData') }, ... }) ``` 最后,在 Vuex 状态变更时,您需要将数据保存到本地存储中: ``` store.subscribe((mutation, state) => { window.localStorage.setItem('vuex-data', JSON.stringify(state)) }) ``` 这样,在页面刷新时,您的 Vuex 状态将被缓存,并在页面重新加载后恢复。 ### 回答2: 页面刷新时如何实现Vuex数据缓存主要可以通过以下几个步骤实现。 首先,我们可以在Vuex的store中使用`localStorage`或者`sessionStorage`来存储数据,这样在页面刷新后可以从中读取之前存储的数据,并将其赋值给Vuex的state。比如在每次mutation改变state时,可以在mutation函数内部使用localStorage或sessionStorage的setItem方法将state的值存储起来。 其次,我们可以在Vue组件的created钩子函数中,从localStorage或sessionStorage中读取之前存储的状态,并通过commit方法将其提交到Vuex的state中。这样可以保证在页面刷新后,重新创建Vue组件时,能够读取到之前存储的状态。 另外,在Vue组件的beforeUnload钩子函数中,可以使用localStorage或sessionStorage的setItem方法将Vuex的state值存储起来。这样可以保证在页面刷新或离开页面时,将最新的state值存储起来,以便下次使用。 最后,我们还可以在Vuex的store中定义一个action方法,在该方法中使用localStorage或sessionStorage的getItem方法读取之前存储的状态,并通过commit方法将其提交到Vuex的state中。然后在Vue组件的created钩子函数中,使用dispatch方法来调用该action方法,从而在页面刷新后能够读取到之前存储的状态。 综上所述,可以通过使用localStorage或sessionStorage和相应的钩子函数来实现Vuex数据缓存,以保证在页面刷新时能够继续使用之前的数据。 ### 回答3: 页面刷新时如何实现Vuex数据缓存是一个常见的问题。Vuex 是一个用于 Vue.js 应用程序的状态管理模式,可以集中存储应用程序的所有组件之间共享的状态数据。在页面刷新时,由于浏览器刷新导致应用程序重启,Vuex 中的数据也会被重置,因此需要一种方式来实现数据的持久化缓存。 一种实现Vuex数据缓存的方式是使用本地存储(local storage)来保存和恢复数据。当页面要被刷新时,可以先将Vuex数据通过localStorage.setItem()方法保存到本地存储中。具体步骤如下: 1. 在Vuex的store中,监听window对象的beforeunload事件,即页面即将被卸载前触发的事件。 ```javascript mutations: { saveData(state) { window.addEventListener('beforeunload', () => { localStorage.setItem('vuexData', JSON.stringify(state.data)) }) } } ``` 2. 添加初始化订阅,用于在页面加载时从本地存储中获取之前保存的数据并更新Vuex的状态。 ```javascript actions: { initDataFromLocalStorage({ commit }) { const data = localStorage.getItem('vuexData') if (data) { commit('updateData', JSON.parse(data)) } } } ``` 3. 在应用程序的入口文件main.js中,通过调用actions的initDataFromLocalStorage方法来初始化Vuex数据。 ```javascript import Vue from 'vue' import store from './store' store.dispatch('initDataFromLocalStorage') new Vue({ store, render: h => h(App) }).$mount('#app') ``` 这样,在页面刷新时,Vuex存储的数据就会被保存到本地存储中,然后在页面重新加载后会初始化Vuex数据,并恢复之前保存的状态。 需要注意的是,使用本地存储保存Vuex数据会增加额外的存储开销,并且当数据量较大时,可能会影响页面的性能。因此,需要根据实际情况来决定是否使用本地存储来实现Vuex数据缓存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值