飞雪连天射白鹿,笑书神侠倚碧鸳

0%

vuex getter

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.aaa
this.$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
/**
* Reduce the code which written in Vue.js for getting the getters
* @param {String} [namespace] - Module's namespace
* @param {Object|Array} getters
* @return {Object}
*/
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;

// The namespace has been mutated by normalizeNamespace
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]
};
// mark vuex getter for devtools
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]
听说,打赏我的人最后都找到了真爱
↘ 此处应有打赏 ↙
// 用户脚本