Vuex 中数据的全局化管理可以使得我们数据更加便于管理,但存在一个缺点就是当页面刷新也就是实例重新创建时,数据就会丢失,而使用 localStorage 就可以使得数据持久化保存,本文就此提供一种解决思路。
1. localStorage 基础
localStorage 是一种缓存机制,即时浏览器关闭后依然可以获取到。这使得你可以在页面上保存一些数据,后续的操作也可以继续访问的到。MDN 网站上有详细介绍,在此不再赘述,下面介绍下它的基本用法,非常简单。下面中的 key 表示获取访问数据的标识符
// 存储
localStorage.setItem(‘key’,’value’);
// 获取
let val = localStorage.getItem(‘key’);
注意:localStorage 只能是字符串,意味着你想要存储对象和数组的话,localStorage 只能先转换成 JSON 格式的字符串,然后获取的时候,再转换回原理的格式。
// 保存数据
localStorage.setItem(‘key’, JSON.stringify(object));
// 数据获取,需转换
let obj = JSON.parse(localStorage.getItem(‘key’));
2. Vuex
Vuex 是 Vue 的一个中央数据管理工具,提供了一种全局存储中心,可以保存组件的数据,并且能够获取,更新和响应式变化。除非你做一个很小的应用,还是强力建议你使用 Vuex 来管理你的数据和状态。
最近在开发一个 Vueapp 应用,碰到个需求,就是,我想要一些数据能够存在 localStorage 中,无论什么时候更新的时候,这就意味着,当用户关闭它们的浏览器或者电脑的时候,然后重新打开页面,数据依然能够显示在页面上。例如电商应用中,当用户添加商品到购物车的时候,页面关闭再打开是,购物车的物品依然能够展示在页面上展示。
2.1 初始化 store
一个 store 实例的典型配置
// 初始化 store
const store new Vuex.Store({
state: {
count: 1
},
mutations: {},
getters: {}
});
2.2 存储数据
我们希望无论 state 对象任何时候更新,数据都能够缓存下来,我们可以在 actions 提交 mutation 来改变 state 中的数据。
// Subscribe
store.subscribe((mutation, state) => {
// 保存数据对象为 JSON 字符串
localStorage.setItem(‘store’, JSON.stringify(state));
});
2.3 获取数据
创建一个方法来获取 `localStorage 保存的数据,首先需要检查数据是否已经存在
const store new Vuex.Store({
state: {
count: 1
},
mutations: {
initialiseStore(state) {
// 检查 ID 是否存在
if(localStorage.getItem(‘store’)) {
}
}
},
getters: {}
});
如果数据存在的话我们需要使用 replaceState 来替换数据。
const store new Vuex.Store({
state: {
count: 1
},
mutations: {
initialiseStore(state) {
// 检查 ID 是否存在
if(localStorage.getItem(‘store’)) {
// 用存储的数据替换掉 state 对象
this.replaceState(
Object.assign(state, JSON.parse(localStorage.getItem(‘store’)))
);
}
}
},
getters: {}
});
最后一步就是当实例创建的时候提交相应的 mutation,我们想要在实例创建的最开始就执行,所以,我们选择在 beforeCreate 的时候触发。
new Vue({
el: ‘#app’,
store,
beforeCreate() {
this.$store.commit(‘initialiseStore’);
}
});
3. 缓存的有效性
在最近的一个项目中使用它时,数据的变化并没有引起相应的变化。这是因为在不清除 localStorage 的情况下改变了 store 的结构。添加值的时候是正常的,但重命名,编辑或更改值时,对应值的类型没有改变。
当使用 semver 进行版本控制的话,可以调用版本号来检查 store 是否是最新版本。
如果在加载时,用户与我的应用版本号相同,则进行缓存处理,否则清除缓存并加载新版本。
注意:会清除整个缓存,因此如果您依赖它来获取用户首选项或类似内容,您可能偏向选择性删除。
第一步是加载我们的版本号。我们存储在 package.json 中,因此,使用 ES6 的话很简单:
import {version} from ‘./package.json’;
但是,如果从 git 标记缓存您的内容或将其作为变量放在某处,它需要与存储分开访问,以便缓存不会完全覆盖它。
接下来,在 store 中创建一个空字符串,以便在验证后保存该版本号。
state: {
// Cache version
version: ”,
count: 1
},
我们现在可以更新 initialiseStore,以使用缓存中的版本号检查版本,并根据返回结果执行不同操作
initialiseStore(state) {
// 检查 store 是否存在
if(localStorage.getItem(‘store’)) {
let store = JSON.parse(localStorage.getItem(‘store’));
// 检查存储的版本号是否与当前相同,不同的话加载缓存中的版本
if(store.version == version) {
this.replaceState(
Object.assign(state, store)
);
} else {
state.version = version;
}
}
}
4. 选择性缓存
当只从 store 中缓存一些元素,可以通过在订阅功能中创建一个新对象并存储它来实现。我们已经在 store 加载时将缓存与当前存储状态合并,因此不需要更改。
store.subscribe((mutation, state) => {
let store = {
version: state.version,
count: 1
};
localStorage.setItem(‘store’, JSON.stringify(store));
});
参考
Vue: Using localStorage with Vuex store
awesome-vue