Vuex的5大属性,state,getters,mutations,actions和modules getters到底能做什么
写业务时没有太在意state/getter读值的区别,直到面试时遇到了这样一个问题
1 vue中computed和vuex中getters有什么相同点
leo:纳尼,这两者还有关联? 面试官:你真的用过vuex? leo:emmm
vuex嘛,大家都知道是中心化的状态管理模式,单向数据流,如图
state保存状态,getters获取state,mutations同步执行改变state,actions异步执行
如何获取state状态 方案一
1 2 this .$store.state.aaathis .$store.getter.bbb
方案二
1 2 3 4 computed: { ...mapState(['aaa' ]), ...mapGetters(['bbb' ]) }
为什么提供了2种方法获取state,他们有什么区别呢
state获取时直接返回
getter可以在获取state时,对state进行操作后返回
1 2 3 4 5 6 7 8 9 10 getters: { getMyListGreaterThanNum(state, getters) { return function (num ) { return state.myList.filter(item => item > num) } } } this .$store.getters["getMyListGreaterThanNum" ](1 )this .$store.getters.getMyListGreaterThanNum(1 )
computed和getters相同点
缓存,和computed一样,当依赖的state改变才会重新计算
在getters中是属性不是函数,不能直接传参
mapGetters 是什么
mapGetters辅助函数,直接返回一个对象,仅仅是将 store 中的 getter 映射到局部计算属性
每次调用都需要this.$store.getters.xxx,非常麻烦,可以用mapGetters语法糖直接合并入computed
1 2 3 4 5 6 7 computed: { ...mapState(['getMyListGreaterThanNum' ]), ...mapGetters("myStore2" , ["getMyListGreaterThanNum" ]); ...mapGetters("myStore2" , {getMyList : "getMyListGreaterThanNum" }); } this .$storestore.getters["myStore2/getMyListGreaterThanNum" ]
mapGetters源码实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 var mapGetters = normalizeNamespace(function (namespace, getters ) { var res = {}; if (!isValidMap(getters)) { console .error('[vuex] mapGetters: mapper parameter must be either an Array or an Object' ); } normalizeMap(getters).forEach(function (ref ) { var key = ref.key; var val = ref.val; val = namespace + val; res[key] = function mappedGetter ( ) { if (namespace && !getModuleByNamespace(this .$store, 'mapGetters' , namespace)) { return } if (!(val in this .$store.getters)) { console .error(("[vuex] unknown getter: " + val)); return } return this .$store.getters[val] }; res[key].vuex = true ; }); return res }); function normalizeNamespace (fn ) { return function (namespace, map ) { if (typeof namespace !== 'string' ) { map = namespace; namespace = '' ; } else if (namespace.charAt(namespace.length - 1 ) !== '/' ) { namespace += '/' ; } return fn(namespace, map) } } function normalizeMap (map ) { if (!isValidMap(map)) { return [] } return Array .isArray(map) ? map.map(function (key ) { return ({ key : key, val : key }); }) : Object .keys(map).map(function (key ) { return ({ key : key, val : map[key] }); }) }
normalizeNamespace函数将传入的改成namespace/getters的分割样式,如果没有namespace,那么直接返回getters
normalizeMap函数将输入的getters对应成store的内部属性,可以使用对象来更改函数的名称
查找属性,找到返回this.$store.getters[val]