本文将对vuex
使用做一个详细的解释,如需要更深入的研究可查看Vuex官网
Vuex是什么?
官方解释:Vuex
是一个专门为Vue
应用程序开发的状态管理模式,它采用集中式存储管理应用的所以组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex
是一个集中式状态管理框架,在进行频繁、复杂的组件间传值的大型项目中,非常适合用Vuex
做状态管理。如果不需要做大型单页面引用,使用Vuex
则显得冗余。
Vuex工作流程图
Vuex
设计符合单向数据流原则,避免子组件修改父组件的状态导致数据流混乱。通过图可以看出,视图view component
->通过dispatch
分发actions
->通过commit
触发mutations
方法->去修改state
->更新视图view component
,
注意:
Vuex
中的状态是响应式的(state
可以更新view
,view
也可以修改state
)- 数据流是单向的
Vuex
中唯一能修改state
只有mutations
- 在
actions
中能够分发mutations
,并且可以进行异步任务
State
Vuex
使用单一状态树,用一个对象就包含了全部的应用层级状态。至此它便作为一个唯一的状态源而存在。这也意味着,每个应用将仅仅含一个store
实例。
state
中包含了store
中所以状态数据
const store = new Vuex.Store({
state:{
count:100,
list:[
{
id:1,
name:'name1'
},
{
id:1,
name:'name2'
}
]
},
});
Getters
类似于Vue
中的计算属性,从state
获取数据处理后返回
const getters = {
countComputed(state){
return state.count+'user'
}
}
Mutation
更改Vuex
的store
中的状态的唯一方法是提交mutation
,类似于Vue
中的methods
,只能进行同步任务
const mutations = {
// mutationTypes是mutation事件类似的常量表示
[mutationTypes.INCREMENT](state,n=1){
state.count += n
}
}
Action
Action
类似于mutation
,但是action
提交的是mutation
,而不是直接变更状态,action
可以做异步操作
const actions = {
incrementAction(ctx,{n}){
ctx.commit(mutationTypes.INCREMENT, n)
},
demo(ctx){
setTimeout(() => {
// 提交mutation
}, 1000);
}
}
Module
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store
就有可能变得相当臃肿。为了解决上述问题,Vuex
允许我们将store
分割成模块,每个模块都拥有自己的state
、mutation
、action
、getter
、
在进行大型项目时,分模块,使得项目易于维护和管理,也便于团队协作开发
本文将使用模块的形式做综合例子
目录文件
Vuex入口文件index.js
在
index.js
中引入各个模块,此文件作为Vuex
入口文件
import Vue from 'vue'
import Vuex from 'vuex'
import userStore from './user'
import productStore from './product'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
userStore,
productStore
}
})
user.js模块
模块一:用户模块。使用mutationTypes,对方法名做统一的管理,减少出错。
import * as mutationTypes from './mutation-types'
const state = {
count:100
}
const getters = {
countComputed(state){
return state.count+'user'
}
}
const mutations = {
[mutationTypes.INCREMENT](state,n=1){
state.count += n
}
}
const actions = {
incrementAction(ctx,{n}){
ctx.commit(mutationTypes.INCREMENT, n)
}
}
export default {
namespaced: true,
state,
getters,
mutations,
actions
}
product.js模块
import * as mutationTypes from './mutation-types'
const state = {
count:1
}
const getters = {
countComputed(state){
return state.count+'product'
}
}
const mutations = {
[mutationTypes.INCREMENT](state,n=1){
state.count += n
}
}
const actions = {
incrementAction(ctx,{n}){
ctx.commit(mutationTypes.INCREMENT,n)
}
}
export default {
namespaced: true,
state,
getters,
mutations,
actions
}
mutation-types
export const INCREMENT = 'increment'
App.vue组件入口
<template>
<div>
{{ userCount }}
{{ productCount }}
<!-- {{ userGetterCount }} -->
<!-- {{ productGetterCount }} -->
</div>
</template>
<script>
import { mapState, mapGetters, mapActions,mapMutations } from 'vuex'
export default {
computed: {
...mapState({
userCount: state => state.userStore.count,
productCount: state => state.productStore.count
}),
...mapGetters({
userGetterCount: 'userStore/countComputed',
productGetterCount: 'productStore/countComputed'
})
},
methods: {
...mapActions({
userIncrement: 'userStore/incrementAction',
productIncrement: 'productStore/incrementAction'
}),
...mapMutations({
userIncrementMu: 'userStore/increment',
productIncrementMu: 'productStore/increment'
})
},
mounted() {
// this.userIncrement({n:-10})
// this.productIncrement({n:1000})
this.userIncrementMu(-10)
this.productIncrementMu(1000)
}
}
</script>