vuex 中辅助函数mapState的基本用法详解
mapState
辅助函数
当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState
辅助函数帮助我们生成计算属性,让你少按几次键:
// store.js /** vuex的核心管理对象模块:store */ import Vue from 'vue'; import Vuex from 'vuex'; import vuexTest from './modules/vuexTest'; Vue.use(Vuex) // 状态对象 const state = { // 初始化状态 这里放置的状态可以被多个组件共享 count: 1, count1: 1, count2: 2, count3: 3, name: 'daming' }; const mutations = {}; const actions = {}; const getters = {}; export default new Vuex.Store({ state, // 状态 mutations, // 包含多个更新state函数的对象 actions, // 包含多个队形事件回调函数的对象 getters, // 包含多个getter计算属性函数的对象 modules: { // 模块化 vuexTest } });
1、在界面或组件中不使用mapState获取vuex中state的状态
虽然将所有的状态放入Vuex,会使状态变化更显式和易调试,但也会使代码变得冗长和不直观。如果有些状态严格属于单个组件,最好还是作为组件的局部状态,比如temp变量,hello, number作为组件的局部状态。
<!-- test.vue --> <template> <div id="example"> {{count}} {{name}} {{helloName}} {{addNumber}} </div> </template> <script> export default { data() { return { hello: 'hello', number: 1, } }, computed: { // 由于 Vuex 的状态存储是响应式的,所以可以使用计算属性来获得某个状态 // 通过下面的计算属性,就可以在当前组件中访问到count,name,helloName,addNumber 在模板中我们通过大括号符号打印出来,当然这些可以在vue中使用,比如在watch中监听,在mounted中使用 // 下面的计算属性涉及到了vuex管理的状态 count() { // 这实际上是ES6中对象的简化写法 完整写法是 count: function { return this.$store.state.count } return this.$store.state.count }, name() { // 这实际上是ES6中对象的简化写法 完整写法是 name: function { return this.$store.state.count } return this.$store.state.count }, helloName: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数 return this.hello + this.$store.state.name }, addNumber: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数 return this.number + this.$store.state.count } // 但有一个问题 // 当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。比如上面的name(),count(),helloName(),显得重复,代码冗长 // 为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键: }, watch: { helloName(newVal,oldVal){ console.log(newVal); console.log(oldVal); } }, mounted(){ console.log(this.helloName); } } </script>
2、在组件、界面中使用mapState获取vuex中state的数据
<!-- test.vue --> <template> <div id="example"> {{count}} {{count1}} {{repeatCount}} {{count3}} {{name}} {{helloName}} {{addNumber}} </div> </template> <script> export default { data() { return { hello: 'hello', number: 1, count2: 2 } }, computed: { /** * 数组形式 * 当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。 * */ ...mapState(["count", "name"]), /** * 对象形式 */ ...mapState({ count, // 这种就是count:"count", 的简写 count1: "count1", repeatCount: "count2", // 当组件中与vuex中的字符已经出现重复时,使用 repeatCount 来映射 store.state.count2 count3: (state) => { // 映射 count3 为 store.state.conut3的值 return state.count3 }, helloName: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数 return this.hello + state.name }, addNumber: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数 return this.number + state.count } }) }, watch: { helloName(newVal, oldVal) { console.log(newVal); console.log(oldVal); } }, mounted() { console.log(this.helloName); } } </script>
3、modules的vuexTest模块中state数据
/** * vuexTest.js * modules 中的数据 */ export default { namespaced: true, state: { moduleVal: 1, moduleName: "战战兢兢" }, getters: { }, mutations: { }, actions: { } }
4、在界面或组件中不使用mapState获取模块modules vuexTest中state的状态
<!-- module test.vue --> <template> <div id="example"> {{moduleVal}} {{moduleName}} {{moduleNameOther}} </div> </template> <script> export default { data() { return { hello: 'hello', number: 1, } }, computed: { moduleVal(){ return this.$store.state.vuexTest.moduleVal }, moduleName(){ return this.$store.state.vuexTest.moduleVal }, moduleNameOther(){ // 当组件中与vuex中的字符已经出现重复时,使用 moduleNameOther 来映射 store.state.vuexTest.moduleName return this.$store.state.vuexTest.moduleVal }, }, watch: { helloName(newVal, oldVal) { console.log(newVal); console.log(oldVal); } }, mounted() { console.log(this.addNumber); } } </script>
5、在界面或组件中使用mapState获取模块modules vuexTest中state的状态
<!-- module test.vue --> <template> <div id="example"> {{moduleVal}} {{moduleName}} {{moduleNameOther}} </div> </template> <script> import { mapState } from 'vuex' export default { data() { return { hello: 'hello', number: 1, } }, computed: { /** * 数组形式 * 当映射的计算属性的名称与 与模块中vuexTest中state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组, * */ ...mapState("vuexTest", ["moduleVal", "moduleName"]), // "vuexTest" 指向模块vuexTest,"moduleVal"表示store.vuexTest.moduleVal /** * 对象形式 */ // 第一种对象方式 ...mapState({ moduleVal: "vuexTest/moduleVal", moduleNameOther: "vuexTest/moduleName" // 表示 moduleNameOther 映射到vuexTest模块中moduleName }), ...mapState("vuexTest", { moduleVal, // 这种就是moduleVal:"moduleVal", 的简写 moduleName: "moduleName", moduleNameOther: "moduleName", // 当组件中与vuex中的字符已经出现重复时,使用 moduleNameOther 来映射 store.state.vuexTest.moduleName moduleVal: (state) => { // 映射 moduleVal 为 store.state.vuexTest.moduleVal的值 return state.moduleVal }, helloName: function (state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数 return this.hello + state.moduleName }, addNumber(state) { // 为了能够使用 `this` 获取局部状态,必须使用常规函数,不能使用箭头函数 return this.number + state.moduleVal } }) }, watch: { helloName(newVal, oldVal) { console.log(newVal); console.log(oldVal); } }, mounted() { console.log(this.addNumber); } } </script>