vuex 实现数据状态持久化

刷新浏览器后,Vuex 的数据是否存在?如何解决?

在 vue 项目中用 vuex 来做全局的状态管理, 发现当刷新网页后,保存在 vuex 实例 store 里的数据会丢失。

原因:因为 store 里的数据是保存在运行内存中的,当页面刷新时,页面会重新加载 vue 实例,store 里面的数据就会被重新赋值初始化。

vuex

  1. State:

vuex 中的数据源,我们需要保存的数据就保存在这里,可以在页面通过 this.$store.state 来获取我们定义的数据;

  1. Getters:

Getter 相当于 vue 中的 computed 计算属性,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算,这里我们可以通过定义 vuex 的 Getter 来获取,Getters 可以用于监听、state 中的值的变化,返回计算后的结果

  1. Mutations:

需要修改 store 中的值唯一的方法就是提交 mutation 来修改

  1. Actions:

提交一个 actions,在 actions 中提交 mutation 再去修改状态值

  1. Module:

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割

数据状态持久化

用过 vuex 的肯定会有这样一个痛点,就是刷新以后 vuex 里面存储的 state 就会被浏览器释放掉,因为我们的 state 都是存储在内存中的。

vuex-persistedstate

通过 vuex-persistedstate 这个插件,来实现将数据存储到本地

  1. vuex 初始化就开始引入;
  2. 每次我们更新 vuex 的状态,localstorage 中的 vuex 也会随之改变;
  3. vuex-persistedstate 默认使用 localStorage 来固化数据。
1
npm install vuex-persistedstate
1
2
3
4
5
6
7
8
9
import createPersistedState from "vuex-persistedstate";
const store = new Vuex.Store({
modules: {
app,
user
},
getters,
plugins: [createPersistedState()] //加上这个就可以了
});

vuex-along

vuex-along 的实质也是将 vuex 中的数据存放到 localStorage 或者 sessionStroage 中,只不过这个存取过程组件会帮我们完成,我们只需要用 vuex 的读取数据方式操作就可以了

安装 vuex-along:

1
npm install vuex-along --save

配置 vuex-along: 在 store/index.js 中最后添加以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
import VueXAlong from "vuex-along"; //导入插件
export default new Vuex.Store({
//modules: {
//controler //模块化vuex
//},
plugins: [
VueXAlong({
name: "store", //存放在localStroage或者sessionStroage 中的名字
local: false, //是否存放在local中 false 不存放 如果存放按照下面session的配置
session: { list: [], isFilter: true } //如果值不为false 那么可以传递对象 其中 当isFilter设置为true时, list 数组中的值就会被过滤调,这些值不会存放在seesion或者local中
})
]
});

使用 localStorage 或者 sessionStroage

1
2
3
4
5
6
7
8
9
10
11
12
export default {
created() {
//在页面加载时读取 sessionStorage 里的状态信息
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));
});
}
};

自定义存储方式

使用 sessionStorage

1
2
3
4
5
const store = new Store({
// ...
plugins: [persistedState({ storage: window.sessionStorage })];
});

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { Store } from "vuex";
import createPersistedState from "vuex-persistedstate";
import * as Cookies from "js-cookie";
const store = new Store({
// ...
plugins: [
createPersistedState({
storage: {
getItem: (key) => Cookies.get(key),
setItem: (key, value) => Cookies.set(key, value, { expires: 3, secure: true }),
removeItem: (key) => Cookies.remove(key)
}
})
]
});