Vuex负责状态管理,将各个组件中的共同状态抽取出来,进行统一管理,方便代码维护。
ps: 当组件深层嵌套时,传递数据会变得非常麻烦;以及兄弟组件之间调用数据也非常麻烦;为了解决上述问题,故而需要Vuex来对vue.js进行集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex中主要包含以下几个核心概念:state、getter、mutation、action、module。
目录
State
概念:获取Vuex状态
使用方式:
// 创建一个Counter组件
const Counter = {
template: '<div>{{ count }}</div>',
computed: {
count() {
// 从store实例中读取状态
return store.state.count
}
}
}
const store = createStore({
state:{
count:0,
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
})
辅助函数:mapState
// 在单独构建的版本中辅助函数为 Vuex.mapState
import { mapState } from 'vuex'
export default {
// ...
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
// 第二种 对象展开运算符
computed: {
localComputed () { /* ... */ },
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
// ...
})
}
Getter
概念:获取从store的state中派生的一些属性
使用方式:
const store = createStore({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos (state) {
return state.todos.filter(todo => todo.done)
},
// 可以接收其它getter作为第二个参数
doneTodosCount (state, getters) {
return getters.doneTodos.length
},
// 通过方法访问,让 getter 返回一个函数,来实现给 getter 传参。在你对 store 里的数组
// 进行查询时非常有用。
// 注意,getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
})
// 以属性的形式访问这些值
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
辅助函数:mapGetters
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// 第一种:使用对象展开运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// ...
])
// 第二种: doneConut为别名
...mapGetters({
// 把 `this.doneCount` 映射为 `this.$store.getters.doneTodosCount`
doneCount: 'doneTodosCount'
})
}
}
Mutation
概念:用于变更store的状态,不可异步;通过store.commit('事件类型')来唤醒一个mutation处理函数。
使用方式:
const store = createStore({
state: {
count: 1
},
mutations: {
increment (state) {
// 变更状态
state.count++
},
// 对应的提交方式 store.commit('increment')
// n为额外传入的参数,即载荷Payload
increment1 (state, payload) {
state.count += payload.amount
}
// 对应的提交方式 store.commit('increment', { amount: 10})
// 对象风格的提交方式 store.commit({ type: 'increment',amount: 10})
}
})
// 使用常量替代 Mutation 事件类型
// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
// store.js
import { createStore } from 'vuex'
import { SOME_MUTATION } from './mutation-types'
const store = createStore({
state: { ... },
mutations: {
// 我们可以使用 ES2015 风格的计算属性命名功能
// 来使用一个常量作为函数名
[SOME_MUTATION] (state) {
// 修改 state
}
}
})
辅助函数:mapMutations
import { mapMutations } from 'vuex'
export default {
// ...
methods: {
...mapMutations([
'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
// `mapMutations` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
})
}
Action
概念:用于提交mutation,可包含任意异步操作;通过store.dispatch('事件类型')来触发
使用方式:
const store = createStore({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
// context是与store实例具有相同方法和属性的对象
increment (context) {
context.commit('increment')
},
// 也会使用ES2015的参数解构来简化代码
increment1 ({ commit }) {
commit('increment')
}
}
})
action通过store.dispatch('increment')触发
辅助函数:mapActions
import { mapActions } from 'vuex'
export default {
// ...
methods: {
...mapActions([
'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
// `mapActions` 也支持载荷:
'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
]),
...mapActions({
add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
})
}
}
Module
概念:每个模块拥有state、getter、mutation、action、甚至是嵌套子模块;为避免所有状态集成到一个比较大的对象,使得store对象变得非常臃肿,从而将store分割成模块(module)。
使用方式:
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = createStore({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态