理解 Vuex 中的 mapGetters

2025-06-07

理解 Vuex 中的 mapGetters

其中vuex有一个经常出现的辅助函数。

computed() {
    ...mapGetters(['currentUser'])
}
Enter fullscreen mode Exit fullscreen mode

我第一次使用它的时候,遇到了一些 Babel 问题,导致我无法使用 ES6 语法,结果无法按预期使用该函数。使用这个变通方法帮助我准确理解了这段代码的作用,所以我想把它写出来。

事实证明,这里发生了几件事。一是mapGetters函数的作用,二是展开语法如何转换结果。让我们先深入研究一下函数本身。

什么是 mapGetters?

在我们的示例中, 的目的mapGetters是将 的结果映射store.getters.currentUser到计算属性currentUser。这允许我们像这样访问 getter 函数的结果。

<div>{{currentUser}}</div>
Enter fullscreen mode Exit fullscreen mode

事实证明,mapGetters它可以接受一个对象或一个数组。所以这就是上面展示的代码片段。

computed() {
    ...mapGetters(['currentUser'])
}
Enter fullscreen mode Exit fullscreen mode

也可以是這樣。

computed() {
    ...mapGetters({currentUser: 'currentUser'})
}
Enter fullscreen mode Exit fullscreen mode

在第一种情况下,名称赋值是隐式的,在第二种情况下,名称赋值是显式的。但这就是唯一的区别。

现在我们知道了该函数的作用,让我们来分解一下。

我一直主张用多种不同的方式来理解概念。所以,我请我的同事读了这篇文章,他是mapGetters这样解释的:
“这个想法是,在视图控制器的 store 对象中获取一组变量,并将它们映射到一个顶级 getter 函数,这样你就可以通过 html 页面上的双向绑定通过名称来调用它了?”

mapGetters

假设我们根本无法使用函数或辅助语法。为了完成同样的事情,我们需要做什么?

我们希望调用 getter 函数,返回结果,并通过某种名称访问该结果。所以我们会这样做。

computed() {
    currentUser() {
         return this.$store.getters.currentUser;
    }
}
Enter fullscreen mode Exit fullscreen mode

我们创建一个函数,并在其中返回 getter 函数的结果。可以使用该函数名访问结果,如本例所示。

<div>{{currentUser}}</div>
Enter fullscreen mode Exit fullscreen mode

请记住,我们使用的名称是计算函数的名称,而不是我们调用的 getter 方法的名称。以下示例的名称并不相同。

computed() {
    otherName() {
         return this.$store.getters.currentUser;
    }
}
Enter fullscreen mode Exit fullscreen mode

为了访问结果,我们将参考otherName

<div>{{otherName}}</div>
Enter fullscreen mode Exit fullscreen mode

很多绑定都来自 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
})
Enter fullscreen mode Exit fullscreen mode

这里有很多代码,其中一些是为了处理对象和数组输入之间的差异,但核心在于函数mappedGetter。它接受返回对象,并使用给定的键,将关联的 getter 函数的结果赋给该值。

多种的

现在我们已经理解了函数本身,接下来让我们将注意力转向扩展语法。理解的关键...mapGetters在于认识到该函数的设计初衷是同时处理多个 getter 调用。我们一开始提到的单个用例仍然有效,但让我们看看这个。

computed() {
    currentUser() {
         return this.$store.getters.currentUser;
    }
    otherThing() {
         return this.$store.getters.otherThing;
    }
    finalThing() {
         return this.$store.getters.finalThing;
    }

}
Enter fullscreen mode Exit fullscreen mode

我们将 getter 函数的结果赋值给函数变量,以便组件内部引用。这和上面做的一样,只不过是同时调用了多个 getter 函数。

这样做可以让我们呈现所有这些结果。

<div>{{currentUser}} {{otherThing}} {{finalThing}}</div>
Enter fullscreen mode Exit fullscreen mode

现在解释...mapGetters 前面的内容就更容易了。

扩展语法

你可能熟悉 ES6 扩展语法。如果你想复习一下,我在这里写了一篇关于它的文章。

这是一个功能强大的语法,可以做很多不同的事情。让我们看看它在示例中做了什么。

我们已经看到,它mapGetters旨在替代多个函数调用。解析后,它返回一个由键值对组成的对象。每个键都是一个字符串名称,每个值都是关联的 getter 函数调用的结果。所以,实际上,我们得到的是类似这样的结果。

computed() {
    ...{'currentUser': currentUser, 'otherThing': otherThing, 'finalThing': finalThing}
}
Enter fullscreen mode Exit fullscreen mode

请注意,这不是有效的 JavaScript!它只是一个抽象。

事实证明,这看起来非常像一个对象字面量。那么扩展语法是如何处理对象字面量的呢?它的作用就像Object.assign()……

如果你不清楚这是什么意思,它实际上完成了以下工作。扩展语法会选择对象内部的每个键值对,并将其作为独立对象提取出来。因此,每个键都可以用来引用存储结果的值,就像我们之前看到的那样。

<div>{{currentUser}} {{otherThing}} {{finalThing}}</div>
Enter fullscreen mode Exit fullscreen mode

现在大家一起

让我们从头看看我们的代码。

computed() {
    ...mapGetters(['currentUser', 'otherThing', 'finalThing'])
}
Enter fullscreen mode Exit fullscreen mode

我们能看到现在发生了什么吗?数组中的每个字符串都由 处理mapGetters。它接受同名的 getter 方法并调用它,然后将结果赋值为以原始字符串为键的值。

mapGetters返回一个包含一系列基于该公式的键值对的对象。然后,扩展语法会将每个键值对提取出来,形成一个独立的对象,可以在模板代码中直接引用。就是这样。

结论

真是太多了!而且你可能永远不会用 mapGetters。不过理解它还是挺酷的,对吧?

文章来源:https://dev.to/laurieontech/understanding-mapgetters-in-vuex-2lba
PREV
成为一名技术顾问意味着什么?顾问的工作内容是什么?需要具备哪些技能?顾问通常服务于哪些类型的客户?我是如何进入这一行的?
NEXT
空值合并 - 别再让 Falsy 欺骗你