4. 项目配置Vuex
1. 配置一个简单的vuex
安装
npm install vuex --save-dev
在项目下配置main.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
...
new Vue({
...
store: store,
})
将store的配置单独提取到src/store/index.js
2. 辅助函数mapState
当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState
辅助函数帮助我们生成计算属性,让你少按几次键
使用方式:
-
当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给
mapState
传一个字符串数组。computed: mapState([ // 映射 this.count 为 store.state.count 'count' ]) // 在组件中直接通过 this.count来访问(count就是当前组件的`计算属性`)
-
映射的计算属性与state的子节点名称不一致
computed: mapState({ // 箭头函数可使代码更简练 count: state => state.count, // 传字符串参数 'count' 等同于 `state => state.count` countAlias: 'count', // 为了能够使用 `this` 指向当前组件,必须使用常规函数 countPlusLocalState (state) { return state.count + this.localCount } })
或者通过对象展开运算符
computed: { ...mapState({ // 箭头函数可使代码更简练 count: state => state.count, // 传字符串参数 'count' 等同于 `state => state.count` countAlias: 'count', // 为了能够使用 `this` 指向当前组件,必须使用常规函数 countPlusLocalState (state) { return state.count + this.localCount } }) }
总结:mapState通过生成计算属性,将Vuex中的状态映射到局部组件。mapState()返回的是一个对象
3. getter和辅助函数mapGetter
getter: 有时候我们需要在store的state中派生一些属性,就可以使用 getter
,它就相当于store的计算属性
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)
}
}
})
在组件中获取方式一:
console.log(this.$store.getters.doneTodos)
在组件中获取方式二:
computed: {
doneTodosCount () {
return this.$store.getters.doneTodosCount
}
}
注意: getter 在通过属性访问时是作为 Vue 的响应式系统的一部分缓存其中的,getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果。
mapGetters: 通过mapGetters在组件中同时导入多个store的计算属性。具体使用方式
4. modules的使用
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
-
每一个modules可以有自己
state
、mutations
、actions
、getters
-
在组件中访问modules名为common的state (状态的获取不受命名空间的影响)
// 直接访问 this.$store.state.common
// 生成计算属性 computed: { ...mapState({ titleForCommon: (state) => state.common.title }) }, // 或者,提取module computed: { ...mapState('common', { titleForCommon: (state) => state.title // 这个state指向 common里的state title: 'title' }) }, // 第一个参数接受一个字符串,字符串为module名,第二个参数接收数组或者对象
-
在组件中访问modules名为common的mutations
默认情况下,模块内的actions, mutations and getters,在全局命名空间下注册-这允许多个模块对相同的actions, mutations and getters做出反应
// 直接访问 // 1. 不设置namespaced = true this.$store.commit('方法名') // 2. 设置namespaced = true this.$store.commit('modules名/方法名')
// 生成方法 methods: { ...mapMutations('common', { changeTitle, }) } // 第一个参数接受一个字符串,字符串为module名,第二个参数接收数组(数组元素直接是mutaions方法名)或者对象(在组件中映射的方法名: mutations方法名)
-
在组件中访问modules名为common的getters
//直接访问 // 1. 不设置namespaced = true this.$store.getters['sumWithRootCount'] // 2. 设置namespaced = true this.$store.getters['common/sumWithRootCount']
在
common.js
里const getters = { sumWithRootCount (state, getters, rootState) { console.log(state, getters, rootState) return 1 } } // getters的计算属性中接受三个参数, // 第一个参数代表common的状态, // 第二个参数代表当前moudule的getters里面的所有计算属性(函数的返回值)-namespaced = true; 否则代表所有getters的计算属性 // 第三个参数代表全局的state