vuex-详细解读
vuex是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
理解:多个组件共享状态(即数据),由vuex统一管理。
核心概念
- state:定义状态属性(变量)
- getters:对数据获取之前的再次编译,相当于状态管理(store)的计算属性。我们在组件中使用 $sotre.getters.add()
- mutations:同步操作。修改状态,通过commit提交mutations,在组件中使用$store.commit('',params)。这个和我们组件中的自定义事件类似。
- actions:异步操作。 通过mutations提交actions,在组件中使用是$store.dispath('')
- modules:由于使用单一状态树,应用的所有状态会集中到一个比较大的对象,对象越大越复杂。
所以Vuex 将 store 分割成模块(module)。
每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割
安装
npm install vuex --save
创建项目
写个demo吧 为方便讲解,文档内容与实际demo有差异,
先总结哈:
1.获取store中某状态属性:通过$store.xxx 或 computed 或 getters 或mapState 或mapGetters
2.同步时:$store.commit—触发—mutaion—改变—state
this.$store.commit('addCount') 可写成 ...mapMutations(['addCount']);
3.异步时:$store.dispatch—提交— mutation —通过—commit —改变—state
this.$store.dispatch('addCount') 可写成 ...mapActions(['addCount']);
4.使用mapMutations,mapActions等 前需要引入
import { mapState,mapGetters, mapMutations,mapActions } from 'vuex';
目录大概如下:
第一步:创建store.js(可自行取名)引入vuex,并且实例化
//store.js中 import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ // 状态属性 state: { count:0, }, // 状态管理中的计算属性 getters:{ }, // 修改state中的值,需改变mutations,改变mutations需用commit mutations: { }, // 管理mutations actions:{ } }) export default store;
第二步:在main.js中引入store.js
import Vue from 'vue' import App from './App' import router from './router' import store from'./store/store.js' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, store, components: { App }, template: '<App/>' })
此时已经正确创建store仓库,并可投入使用了。
下面如何获取store中的count呢?
1.第一种:通过$store.state.count
<h2>{{$store.state.count}}</h2>
2.第二种:本身计算属性computed取值
<h2>{{getCount}}</h2>
computed:{ getTest(){ return this.$store.state.count; } }
3.第三种:通过getters取值(即相当于通过状态管理中的计算属性取值)
<p>count:{{$store.getters.getCount}}</p>
//在stores.js中
// 状态管理中的计算属性 getters:{ getCount(state){ return state.count+=2; }, },
4.第四种:通过mapState
辅助函数取值
<h1>hello ,{{count}}</h1>
//组件中HelloWorld中 import { mapState} from 'vuex'; export default { computed:{ ...mapState(['count']) }, }
5.第五种:通过mapGetters
辅助函数取值
<h2>{{getCount}}</h2>
//在stores.js中getters中必须存在相应的方法getCount()
// 状态管理中的计算属性
getters:{
getCount(state){ return state.count+=2; },
},
//在组件HelloWorld.vue中使用 import { mapGetters} from 'vuex'; computed:{ ...mapGetters(['getCount']),//相当于this.getCount = this.$store.getters.getCount },
同步时,如何修改count?如果传参?
在helloWorld.vue 的template中
<p> <!-- 第一种:写在函数里 -->
<!--不传参-->
<button @click="addCount()">加</button>
<!--传参--> <button @click="add(5)">加</button>
<!-- 第二种:直接写表达式 --> <!-- 通过commit修改mutations中的,commit('xxxx',n) xxx代表mutations中的xxxx方法,n表示参数--> <button @click="$store.commit('add',5)">每次加5</button> </p>
在helloWorld.vue 的script中
add(){ //commit触发mutations this.$store.commit('addCount'); }, addCount(){ this.$store.commit('addCount'); },
等价于: 使用mapMutations辅助函数
//将this.add映射到this.$store.commit('addCount'); ...mapMutations({ add:'addCount' }), //方法名与mutations中名字一样时可简写 【注:mapMutations绑定数组 ...mapMutations(['aaa','bbb']);】 ...mapMutations(['addCount']);
至于mapMutations如何传参暂无,还有待研究?????
在store.js中
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ // 状态属性 state: { count:0, }, // 状态管理中的计算属性 getters:{ getCount(state){ return state.count+=2; }, }, // 修改state中的值,需改变mutations,改变mutations需用commit mutations: { add(state,n){ console.log('增加count'); state.count+=n; }, addCount(state){ console.log('增加count,无参数'); state.count++; }, }, }) export default store;
异步时,如何修改msg?如果传参?
其实与同步操作差不多,只是要通过actions来提交mutations
在helloWorld.vue 的template中
<button @click="a_changeMsg()">点击后2000ms修改msg</button> <p>msg:{{$store.state.msg||'暂无'}}</p>
在helloWorld.vue 的script中
a_reduce(){ this.$store.dispatch('a_reduce'); },
等价于:
...mapActions({ a_changeMsg:'a_changeMsg' })
在store.js中
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ // 状态属性 state: { msg:'', }, // 状态管理中的计算属性 getters:{ }, // 修改state中的值,需改变mutations,改变mutations需用commit mutations: { changeMsg(state){ state.msg="我是状态管理" } }, // 管理mutations actions:{ a_changeMsg({commit}){ setTimeout(()=>{ console.log('2000秒后修改msg') commit('changeMsg') },2000); }, } }) export default store;