Vuex是一个状态管理的插件,管理过程包含了state(数据源)、view(state绑定到视图)、actions(view改变同步改变数据源)三个状态,页面刷新的时候vuex里的数据会重新初始化,导致数据丢失,页面会重新加载vue实例,vuex里面的数据就会被重新赋值,解决办法:将vuex中的数据直接保存到浏览器缓存中(sessionStorage、localStorage、cookie),界面刷新前把数据存sessionStorage或再次请求远程数据,使之动态更新vuex数据,App.vue中添加以下代码
// App.vue
//===========================下面是解决刷新页面丢失vuex数据
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
之类的里面或涉及到非父子关系的组件,例如兄弟关系、祖孙关系,甚至更远的关系组件之间的联系cookies
Vuex使用:
- 安装:cnpm install vuex --save
- 引入:import Vuex from 'vuex' Vue.use(Vuex)
- 创建: new Vuex.Store({})
- 使用:挂载到new Vue()上,new Vue({store })
new Vuex.Store 配置
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
},
mutations: {
todosAdd(state,obj) {
// 变更状态
state.todos.push(obj)
}
},
actions: {
todosAddM(context,obj){ // context属性:state、rootState、commit、dispatch、getters、rootGetters
context.commit('todosAdd',obj)
}
},
modules: {
a: moduleA, // moduleA配置和根模块的选项一样,store.state.a // -> moduleA 的状态
b: moduleB
}
})
export default store;
- store、modules:存储数据
- getters:计算属性,可以理解为跟computed一样,访问 store.getters.doneTodos
- mutations:通过里面方法改变state里面的数据,通过 store.commit('todosAdd',{id: 3,text:'''}) 调用,同步处理
- actions:不能直接修改state,通过触发mutations来修改,可操作异步、多个同步处理,通过 store.dispatch('todosAddM',{id: 3,text:'''})调用
Store读取
- 可以直接
时从中读取created
值,通过$store.state
来修改值commit()
- mapState、mapGetters、mapActions、mapMutations:当一个组件需要获取多个状态时使用,import { mapState } from 'vuex'
<template> <div id="example"> {{count}} </div> </template> <script> import { mapState } from 'vuex' export default { data () { return { str: '国籍', dataCount: this.$store.state.count } }, computed: mapState({ count: 'count', // 第一种写法 from: function (state) { // 用普通函数this指向vue实例,要注意 return this.str + ':' + state.from } }), methods: { increment () { this.$store.commit('increment') }, decrement () { this.$store.commit('decrement') } }, created () { // 写个定时器,发现computed依旧保持了只要内部有相关属性发生改变不管是当前实例data中的改变,还是vuex中的值改变都会触发dom和值更新 setTimeout(() => { this.str = '国家' }, 1000) } } </script>