理解 Vuex 中的 mapGetters
其中vuex
有一个经常出现的辅助函数。
computed() {
...mapGetters(['currentUser'])
}
我第一次使用它的时候,遇到了一些 Babel 问题,导致我无法使用 ES6 语法,结果无法按预期使用该函数。使用这个变通方法帮助我准确理解了这段代码的作用,所以我想把它写出来。
事实证明,这里发生了几件事。一是mapGetters
函数的作用,二是展开语法如何转换结果。让我们先深入研究一下函数本身。
什么是 mapGetters?
在我们的示例中, 的目的mapGetters
是将 的结果映射store.getters.currentUser
到计算属性currentUser
。这允许我们像这样访问 getter 函数的结果。
<div>{{currentUser}}</div>
事实证明,mapGetters
它可以接受一个对象或一个数组。所以这就是上面展示的代码片段。
computed() {
...mapGetters(['currentUser'])
}
也可以是這樣。
computed() {
...mapGetters({currentUser: 'currentUser'})
}
在第一种情况下,名称赋值是隐式的,在第二种情况下,名称赋值是显式的。但这就是唯一的区别。
现在我们知道了该函数的作用,让我们来分解一下。
我一直主张用多种不同的方式来理解概念。所以,我请我的同事读了这篇文章,他是
mapGetters
这样解释的:
“这个想法是,在视图控制器的 store 对象中获取一组变量,并将它们映射到一个顶级 getter 函数,这样你就可以通过 html 页面上的双向绑定通过名称来调用它了?”
mapGetters
假设我们根本无法使用函数或辅助语法。为了完成同样的事情,我们需要做什么?
我们希望调用 getter 函数,返回结果,并通过某种名称访问该结果。所以我们会这样做。
computed() {
currentUser() {
return this.$store.getters.currentUser;
}
}
我们创建一个函数,并在其中返回 getter 函数的结果。可以使用该函数名访问结果,如本例所示。
<div>{{currentUser}}</div>
请记住,我们使用的名称是计算函数的名称,而不是我们调用的 getter 方法的名称。以下示例的名称并不相同。
computed() {
otherName() {
return this.$store.getters.currentUser;
}
}
为了访问结果,我们将参考otherName
。
<div>{{otherName}}</div>
很多绑定都来自 Vue。您可以在这里阅读更多内容。
深切
如果您想深入了解,这里是的源代码mapGetters
。
/**
* Reduce the code which written in Vue.js for getting the getters
* @param {String} [namespace] - Module's namespace
* @param {Object|Array} getters
* @return {Object}
*/
export const mapGetters = normalizeNamespace((namespace, getters) => {
const res = {}
normalizeMap(getters).forEach(({ key, val }) => {
// The namespace has been mutated by normalizeNamespace
val = namespace + val
res[key] = function mappedGetter() {
if (
namespace &&
!getModuleByNamespace(this.$store, 'mapGetters', namespace)
) {
return
}
if (
process.env.NODE_ENV !== 'production' &&
!(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
})
这里有很多代码,其中一些是为了处理对象和数组输入之间的差异,但核心在于函数mappedGetter
。它接受返回对象,并使用给定的键,将关联的 getter 函数的结果赋给该值。
多种的
现在我们已经理解了函数本身,接下来让我们将注意力转向扩展语法。理解的关键...mapGetters
在于认识到该函数的设计初衷是同时处理多个 getter 调用。我们一开始提到的单个用例仍然有效,但让我们看看这个。
computed() {
currentUser() {
return this.$store.getters.currentUser;
}
otherThing() {
return this.$store.getters.otherThing;
}
finalThing() {
return this.$store.getters.finalThing;
}
}
我们将 getter 函数的结果赋值给函数变量,以便组件内部引用。这和上面做的一样,只不过是同时调用了多个 getter 函数。
这样做可以让我们呈现所有这些结果。
<div>{{currentUser}} {{otherThing}} {{finalThing}}</div>
现在解释...
mapGetters 前面的内容就更容易了。
扩展语法
你可能熟悉 ES6 扩展语法。如果你想复习一下,我在这里写了一篇关于它的文章。
这是一个功能强大的语法,可以做很多不同的事情。让我们看看它在示例中做了什么。
我们已经看到,它mapGetters
旨在替代多个函数调用。解析后,它返回一个由键值对组成的对象。每个键都是一个字符串名称,每个值都是关联的 getter 函数调用的结果。所以,实际上,我们得到的是类似这样的结果。
computed() {
...{'currentUser': currentUser, 'otherThing': otherThing, 'finalThing': finalThing}
}
请注意,这不是有效的 JavaScript!它只是一个抽象。
事实证明,这看起来非常像一个对象字面量。那么扩展语法是如何处理对象字面量的呢?它的作用就像Object.assign()
……
如果你不清楚这是什么意思,它实际上完成了以下工作。扩展语法会选择对象内部的每个键值对,并将其作为独立对象提取出来。因此,每个键都可以用来引用存储结果的值,就像我们之前看到的那样。
<div>{{currentUser}} {{otherThing}} {{finalThing}}</div>
现在大家一起
让我们从头看看我们的代码。
computed() {
...mapGetters(['currentUser', 'otherThing', 'finalThing'])
}
我们能看到现在发生了什么吗?数组中的每个字符串都由 处理mapGetters
。它接受同名的 getter 方法并调用它,然后将结果赋值为以原始字符串为键的值。
mapGetters
返回一个包含一系列基于该公式的键值对的对象。然后,扩展语法会将每个键值对提取出来,形成一个独立的对象,可以在模板代码中直接引用。就是这样。
结论
真是太多了!而且你可能永远不会用 mapGetters。不过理解它还是挺酷的,对吧?
文章来源:https://dev.to/laurieontech/understanding-mapgetters-in-vuex-2lba