Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
核心概念5个
1: state:数据源 相当于多个组件之间的公共存储空间
const Counter = {
template: `{{ count }}`,
computed: {
count () {
return this.$store.state.count
}
}
}
2: getter: 对state中存储的数据进行过滤操作(不是改变),类似computed计算属性
computed: {
doneTodosCount () {
return this.$store.state.todos.filter(todo => todo.done).length
}
}
getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
// 通过属性访问(有缓存)
this.$store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
3: Mutations :改变数据方法的集合,必须是同步函数
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state, n) {
// 变更状态
// state.count++
state.count += n
}
}
})
//页面调用方式,需要先提交,commit同步操作
this.$store.commit('increment')
this.$store.commit('increment', 10)
4: Actions: Action类似于Mutations,不同点:
- Action提交的是mutations ,而不是直接改变状态
- Action可以包含任意异步操作
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用
context.commit 提交一个 mutation,或者通过 context.state 和 context.getters
来获取 state 和 getters。 但是context != store
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
// context具有state,getter,commit等属性
increment (context) {
context.commit('increment')
}
}
})
// 页面调用方法,dispatch方法是异步操作,返回promise
this.$store.dispatch('increment')
this.$store.dispatch('increment', 2)
5: Modules:Vuex将store分割成 模块(module)每个模块拥有自己的 state、mutation、action、getter
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
state: {},
getter: {},
mutations: {},
actions: {},
modules: {
a: moduleA,
b: moduleB
}
})
this.$store.state.a // -> moduleA 的状态
this.$store.state.b // -> moduleB 的状态
// module/moduleA.js
const state = {
products: 'aaa'
}
const getter = {}
const mutations = {
setProducts(state, payload) {
state.count += payload;
}
}
const actions = {}
export default {
namespaced: true,
state,
getter,
mutations,
actions
}
// store.js
import moduleA from 'module/moduleA.js'
import moduleB from 'module/moduleB.js'
export default {
state: {},
getter: {},
mutation: {
increate(state, payload) {
state.count += payload;
}
},
actions: {
increateAsyn(content, payload) {
setTimeout(() => {
content.commit('increate', payload)
}, 2000)
}
},
modules: {
moduleA
moduleB
}
}
// 页面获取
import { mapMutations, mapActives } from vuex
export default {
computed: {
...mapState('moduleA', ['products']) // 映射模块中的state状态
},
methods: {
...mapMutations(['increate']), // 映射$store.commit('increate', 3)
...mapActives(['increateAsyn']) // 映射$store.dispatch('increateAsyn', 5),
...mapMutations('moduleA', ['setProducts']) // 映射模块中的mutations
}
}
6: