什么是Vuex
Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
其实就是一个为Vue.js设计的数据仓库,就是把各个组件公用的数据放到一个仓库里面进行统一的管理,这样既使得非父子组件间的数据共享变得简单明了,也让程序变得更加可维护(将数据抽离了出来),而且只要仓库里面的数据发生了变化,在其他组件里面数据被引用的地方也会自动更新。
应用场景
如果你的项目里有很多页面(组件/视图),页面之间存在多级的嵌套关系,此时,这些页面假如都需要共享一个状态的时候,此时就会产生以下两个难以解决的问题:
- 多个视图依赖同一个状态
- 来自不同视图的行为需要变更同一个状态
而Vuex可以将组件的共享状态抽取出来,以一个全局单例模式管理。此时任何组件都可以直接访问到这个状态,或者当状态发生改变时,所有的组件都获得更新。
使用时机
- 这个问题因人而异,如果你不需要开发大型的单页应用,此时你完全没有必要使用
Vuex。- 如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,
Vuex将会成为自然而然的选择。
Vuex的流程
store的使用
“store” 基本上就是一个容器,它包含着应用中大部分的状态 ( state )。
-
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
-
改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得可以方便地跟踪每一个状态的变化。
- 在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,
// 定义一个list,以供全局使用
list: [
{ id: 1, name: '111' },
{ id: 2, name: '222' },
{ id: 3, name: '333' },
],
},
});
export default store;
- 添加到vue实例上
import Vue from 'vue';
import App from './App';
import router from './router';
import store from './store'; // 引入我们前面导出的store对象
Vue.config.productionTip = false;
new Vue({
el: '#app',
router,
store, // 把store对象添加到vue实例上
components: { App },
template: '<App/>',
});
App.vue上的使用
<template>
<div></div>
</template>
<script>
export default {
mounted() {
// 使用this.$store.state.XXX可以直接访问到仓库中的状态
console.log(this.$store.state.name);
},
};
</script>
State
存数据的地方,所有的数据都要存在state里面。这样理解起来就简单多了
Getter
可以认为是 store 的计算属性
Mutations
唯一能够修改数据的方法就是提交mutation,里面存的就是一些操作数据的方法,且必须为同步函数。
Actions
修改state的时候有异步操作,vuex作者不希望你将异步操作放在Mutations中,所以就给你设置了一个区域,让你放异步操作,这就是Actions。
Module
拆分项目时,如果将getters/actions/mutations等属性拆分到不同的文件中,采用的是按属性的方式去拆分。
按功能拆分的话,就是 Module(模块) 。将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。
展开运算符和辅助函数
每次都写this.$store.XXX让你感到厌烦,可以使用下面这些辅助函数配合展开运算符代替常用属性。
mapState
mapGetters
mapMutations
mapActions
<script>
import { mapState, mapGetters, mapMutations,mapActions} from 'vuex';
export default {
mounted() {
console.log(this.name);
console.log(this.getMessage);
this.setNumberIsWhat({ number: 999 });
},
computed: {
...mapState(['name']),
...mapGetters(['getMessage']),
},
methods: {
// 注意,mapMutations是解构到methods里面的,而不是计算属性了
...mapMutations(['setNumberIsWhat']),
// ...mapActions(['setNum']), // 就像这样,解构到methods中
},
// async mounted() {
// await this.setNum({ number: 123 }); // 直接这样调用即可
// },
};
</script>