定义
vuex是一个专门为vue设计的集中式状态管理架构.
可以简单理解成data中的属性值,可以在任意组件中操作.
使用
1 2
| //1.下载安装vuex npm i vuex --save
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| 2.引入 // store.js import Vue from 'vue'; import Vuex from 'vuex';
// 3.用Vue.use()进行引用 Vue.use(Vuex);
// 4.初始化store const store = new Vuex.Store({ }) export default store
|
1 2 3 4 5 6 7 8 9
| // main.js(入口文件) // 5.实例化Vue对象时加入store对象 import store from './store';
new Vue({ render: h => h(App), router, store, }).$mount('#app')
|
核心用法state,getter,actions,mutations
1.state
state 就是自己定义的一个数据结构,里面放通用的状态.(就是要公用的属性值)
1 2 3 4 5
| // state.js const state = { name:'hjai', age:'27' }
|
在页面中通过vuex访问.
1 2
| this.$vuex.state.name //'hjai'
|
2.mutations
官方定义:更改Vuex的store中的状态的唯一方法就是提交mutaition.
需要注意:Mutations必须是同步函数。
1.每个mutation
都有个字符串事件类型(type)和一个回调函数(handler),并且它会接受state作为第一个参数.
1 2 3 4 5 6 7
| // mutaition.js const mutations = { ADDAGE(state){ state.age++; } } (Vue建议我们mutation事件类型用大写常量表示.)
|
不能直接调用.其实有点类似事件注册的样子.
先注册一个类型为ADDAGE
的mutation
,再使用以相应的type派发store.commit
.
1
| this.$store.commit('ADDAGE');
|
2.也可以接受第二个参数
1 2 3 4 5 6 7 8 9
| // mutaition.js const mutations = { ADDAGE(state,n){ state.age += n; } }
// 调用 this.$store.commit('ADDAGE',10);
|
3.接受一个payload对象
1 2 3 4 5 6 7 8 9 10 11 12 13
| // mutaition.js const mutations = { ADDAGE(state,payload){ state.age += payload.firtst + payload.second; } }
// 调用 this.$store.commit({ type:'ADDAGE', first:1, second:2 });
|
4.map映射
是不是觉得触发事件代码太长,vuex已经映射好了.
mutations
也有映射函数mapMutations
,帮助我们简化代码,使用mapMutations
辅助函数将组件中的methods映射为$store.commit
调用
1 2 3 4 5 6 7 8 9 10 11
| import {mapMutations} from 'vuex';
// ... methods:{ ...mapMutations([ 'ADD_AGE', 'CHANGE_NAME' ]) }
// 将this.ADD_AGE()映射为this.$store.commit('ADD_AGE');
|
1 2 3 4 5 6 7 8 9
| import { mapMutations } from 'vuex' export default { methods: { ...mapMutations({ add: 'increment' // 映射 this.add() 为 this.$store.commit('increment') }) } } 这样我们可以在vue文件里直接调用函数:this.add()而不用this.$store.commit('increment')这样写了,简化了很多。
|
3.action
action类似于mutation.
不同点:
action提交的是mutation,而不是直接变更状态. (异步改变state状态)
action可以包含任意异步操作.
action 和mutions 的定义方法是类似的,我们要dispatch 一个action, 所以actions 肯定有一个名字,dispatch action 之后它要做事情,就是commit mutation, 所以还要给它指定一个函数。
因为要commit mutation ,所以 函数也会自动获得一个默认参数context, 它是一个store 实例,通过它可以获取到store 实例的属性和方法,如 context.state 就会获取到 state 属性, context.commit 就会执行commit命令。
其实actions 还可以简写一下, 因为函数的参数是一个对象,函数中用的是对象中一个方法,我们可以通过对象的解构赋值直接获取到该方法。修改一下 actions
1 2 3 4 5 6 7 8 9 10
| //actions.js
const actions = { ACTION_TEST(context){ context.commit('ADD_AGE'); } }
//通过store.dispatch触发 this.$store.dispatch('ACTION_TEST');
|
2.actions 支持同样的载荷方式和对象方式进行分发.
1 2 3 4 5 6 7 8 9 10
| // 以载荷形式分发 store.dispatch('incrementAsync', { amount: 10 })
// 以对象形式分发 store.dispatch({ type: 'incrementAsync', amount: 10 })
|
3.映射
1 2 3 4 5 6 7 8
| import {mapActions} from Vuex; methods:{ ...mapActions{[ "add":"increment "//函数命名不相同 // "increment ":"increment "//函数命名相同 ]} } 调用:this.add()即可。相同时候调用:this.increment()
|
4.getter
getter怎么理解呢?通俗的理解可以认为是getter里的函数就是vuex里的计算属性,类似于computed函数
1 2 3 4 5
| // getter.js export default { countAdd: state=>state.age + 2, countDel: state=>state.age - 2, }
|
到页面对computed
进行配置.
1 2 3 4 5 6 7 8 9 10
| computed: { addTwo() { return this.$store.getters.countAdd; }, ...mapGetters(["countDel"])//映射 } 页面: {{addTwo}} {{countDel}}
|
5.modules
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| const moduleA = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } }
const moduleB = { state: { ... }, mutations: { ... }, actions: { ... } }
const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } })
store.state.a // -> moduleA 的状态 store.state.b // -> moduleB 的状态
|
总结起来:mutation 只管存,你给我(dispatch)我就存;action只管中间处理,处理完我就给你,你怎么存我不管(所有的改变state状态的都是mutation 来操作);Getter 我只管取,我不改的(类似计算属性)。