什么是vuex
vuex是一个程序里面的状态管理模式,它是集中式存储所有组件的状态的小仓库,并且保持我们存储的状态以一种可以预测的方式发生变化。
那么什么情况下使用vuex呢
如果数据还有其他组件复用,建议使用vuex
如果需要跨多级组件传递数据,建议使用vuex
需要持久化的数据(如登录后用户的信息),建议使用vuex
vuex的使用
在src路径下创建store文件夹,然后创建index.js文件,文件内容如下:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
// 定义一个name,以供全局使用
name: '张三',
// 定义一个number,以供全局使用
number: 0,
},
});
export default store;
在main.js中引入
import Vue from 'vue';
import App from './App';
import router from './router';
import store from './store'; // 引入我们前面导出的store对象
new Vue({
el: '#app',
router,
store, // 把store对象添加到vue实例上
components: { App },
template: '<App/>'
});
在组件中调用
<template>
<div></div>
</template>
<script>
export default {
mounted() {
// 使用this.$store.state.XXX可以直接访问到仓库中的状态
console.log(this.$store.state.name); //张三
}
}
</script>
官方建议,将操作this.$store.state.XXX放在计算属性中以及简写
<script>
import { mapState } from 'vuex'; // 从vuex中导入mapState
export default {
mounted() {
console.log(this.name);//张三
},
computed: {
...mapState(['name']), // 经过解构后,自动就添加到了计算属性中,此时就可以直接像访问计算属性一样访问它
},
}
</script>
现在已经可以获取到值了,那么如何修改值呢? -->mutations
在store/index.js 添加mutations
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
name: '张三',
number: 0,
},
mutations: {
setNumberIsWhat(state, number) { // 增加一个带参数的mutations方法
state.number = number;
},
},
});
export default store;
在组件中使用
<script>
export default {
mounted() {
this.$store.commit('setNumberIsWhat', 666);
console.log(`新值:${this.$store.state.number}`);//666
},
}
</script>
官方建议,就像最开始的mapState一样,我们在组件中可以使用mapMutations以代替this.$store.commit(‘XXX’)
<script>
import { mapMutations } from 'vuex';
export default {
mounted() {
this.setNumberIsWhat(999);
},
methods: { // 注意,mapMutations是解构到methods里面的,而不是计算属性了
...mapMutations(['setNumberIsWhat']),
},
}
</script>
注意::Mutations里面的函数必须是同步操作,不能包含异步操作!
那么有异步操作怎么办呢,接下来看 异步操作:Actions
Actions存在的意义是假设你在修改state的时候有异步操作,vuex作者不希望你将异步操作放在Mutations中,所以就给你设置了一个区域,让你放异步操作,这就是Actions
在store/index.js中添加actions
const store = new Vuex.Store({
state: {
name: '张三',
number: 0,
},
mutations: {
setNumberIsWhat(state, number) {
state.number =number;
},
},
actions: { // 增加actions属性
setNum(content) { // 增加setNum方法,默认第一个参数是content,其值是复制的一份store
return new Promise(resolve => { // 我们模拟一个异步操作,1秒后修改number为888
setTimeout(() => {
content.commit('setNumberIsWhat',888);
resolve();
}, 1000);
});
}
}
});
在组件中调用
async mounted() {
await this.$store.dispatch('setNum');
console.log(`新值:${this.$store.state.number}`);//888
},
官方建议:你可以采用mapActions的方式,把相关的actions解构到methods中,用this直接调用:
<script>
import { mapActions } from 'vuex';
export default {
methods: {
...mapActions(['setNum']), // 就像这样,解构到methods中
},
async mounted() {
await this.setNum(); // 直接这样调用即可
},
}
</script>
vuex数据持久化
vuex可以进行全局的状态管理,但刷新后刷新后数据会消失,这是我们不愿意看到的。怎么解决呢,我们可以结合本地存储做到数据持久化,也可以通过插件 vuex-persistedstate。
1.利用HTML5的本地存储
vuex的state在localStorage或sessionStorage或其它存储方式中取值
在mutations,定义的方法里对vuex的状态操作的同时对存储也做对应的操作。
这样state就会和存储一起存在并且与vuex同步
2.利用vuex-persistedstate插件
插件的原理其实也是结合了存储方式,只是统一的配置就不需要手动每次都写存储方法
安装
npm install vuex-persistedstate --save
在store/index.js中添加
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState()]
})
默认存储到localstorage,想要存储到sessionStorage 可以:
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage
})]
})
指定需要持久化的state,配置如下
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage,
reducer(val) {
return {
// 只储存state中的assessmentData
assessmentData: val.assessmentData
}
}
})]
如果感觉插件性能不好的话,那么可以监听浏览器刷新,刷新之前把vuex存本地,在路由拦截处获取本地储存,放进vuex并删除本地储存,可以自由控制存localStorage和sessionStorage