Vuex -- 全局状态管理器
Vuex的核心是一个store(仓库), 一个‘非凡的全局对象’, store中的状态发生变化时,与之绑定的视图会被重新渲染。
因为store中的状态不允许被直接修改,改变store中状态的唯一途径就是显示地提交(commit) mutation。
Vuex中有5个重要的感念:State, Getter, Mutation, Action, Module。
State:
用于维护所有应用层的状态,并确保应用只有唯一的数据源
用法:
new Vuex.Store({
state:{
count: 1
}
})
在组件中,可以直接使用$store.state.count(store已经被注册到实例),也可以用mapState辅助函数映射
import { mapState } from 'vuex'
export default{
computed:{
...mapState(['count'])
}
}
Getter:
维护所有State派生的一些状态, 这些状态随着State状态的变化而变化。和计算属性一样,Getter中的派生状态在计算之后会被缓存,重复调用时如果依赖状态没有变化,Vuex不会重新计算派生状态.
Getter用法:
new Vuex.Store({
state:{
count: 1
},
getters:{
tenTimesCount(state){
return state.count * 10
}
}
})
在组件中,可以直接使用$store.getters.tenTimesCount,也可以用使用mapGetters辅助函数映射
import { mapState, mapGetters } from 'vuex'
export default{
computed:{
...mapState(['count'])
...mapGetters(['tenTimesCount'])
}
}
Mutation:
提供修改State状态的方法。
用法:
new Vuex.Store({
state:{
count: 1
},
getters:{
tenTimesCount(state){
return state.count * 10
}
},
mutations:{
addCount(state, value){
state.count += value || 1
}
}
})
在组件中,可以直接使用store.commit 来提交mutation
methods:{
addCount () {
this.$store.commit('addCount')
}
}
也可以用使用mapMutation 辅助函数映射
import { mapState, mapGetters, mapMutations } from 'vuex'
export default{
computed:{
...mapState(['count'])
...mapGetters(['tenTimesCount'])
},
methods:{
...mapMutations(['addCount']),
...mapMutations({ //为addCount赋别名,注意冲突,不常用
increaseCount: 'addCount'
})
}
}
Action:
类似Mutation,
不同点:
- Action不能直接修改状态,智能通过mutation来修改
- Action可以包含异步操作
用法:
new Vuex.Store({
state:{
count: 1
},
getters:{
tenTimesCount(state){
return state.count * 10
}
},
mutations:{
addCount(state, value){
state.count += value || 1
}
},
actions:{
//context具有和store实例相同的属性和方法
//也可以通过context获取state和getters中的值,或者提交mutataion和分发其他的action
addCountAsync(context, num){
setInterval( () => {
if(context.state.count < 2000){
context.commit('addCount', num || 100)
}
}, num || 100)
}
}
})
在组件中,可以直接使用store.dispatch来分发action
methods:{
addCountAsync(num){
this.$store.dispatch('addCountAsync', num)
}
}
或者使用mapActions 辅助函数映射
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default{
computed:{
...mapState(['count'])
...mapGetters(['tenTimesCount'])
},
methods:{
...mapMutations(['addCount']),
...mapMutations({ //为addCount赋别名,注意冲突,不常用
increaseCount: 'addCount'
})
...mapActions (['addCountAsync']),
...mapActions ({ //为addCountAsync赋别名,注意冲突,不常用
increaseCountAsync: 'addCountAsync'
})
}
}
Module:
Vuex允许我们将store分割成模块(Module),每个模块拥有的独立的State、Getter、Mutation、Action,模块之间可以嵌套模块,每一级拥有相同的结构
用法:
const counter = {
namespaced: true, //定义为独立的命名空间
state:{
count: 0
},
getters:{
//在模块中,计算方法还会具有rootState, rootGetters参数以获取跟模块中的数据
tenTimesCount(state, getters, rootState, rootGetters){
console.log(state, getters, rootState, rootGetters)
return state.count * 10
}
},
mutations:{
addCount(state, value){
state.count += value || 1
}
},
actions:{
//context具有和store实例相同的属性和方法
//也可以通过context获取state和getters中的值,或者提交mutataion和分发其他的action
addCountAsync(context, num){
setInterval( () => {
if(context.state.count < 2000){
context.commit('addCount', num || 100)
}
}, num || 100)
}
}
}
new Vuex.Store({
modules: { //注册模块
counter
}
})
组件中的用法:
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
export default{
computed:{
//辅助函数的第一个参数为模块的名称
...mapState('counter', ['count'])
...mapGetters('counter', ['tenTimesCount'])
},
methods:{
...mapMutations('counter', ['addCount']),
...mapActions ('counter', ['addCountAsync'])
}
}