如何将 Vuex mapGetters 与 Vue 3 SFC 脚本设置语法一起使用?

Posted

技术标签:

【中文标题】如何将 Vuex mapGetters 与 Vue 3 SFC 脚本设置语法一起使用?【英文标题】:How to use Vuex mapGetters with Vue 3 SFC Script Setup syntax? 【发布时间】:2021-01-08 14:22:55 【问题描述】:

我正在将组件从常规的 Vue 3 组合 API 重构为脚本设置语法。起点:

<script lang="ts">
import  defineComponent, computed  from 'vue';
import  mapGetters  from 'vuex';

export default defineComponent(
  name: 'MyCoolBareComponent',
  computed: 
    ...mapGetters('auth', ['isAdmin']),
  ,
);
</script>

当前Vue v3 migration documentation,SFC 组合 API 语法糖(),指向此 RFC 页面的链接:https://github.com/vuejs/rfcs/pull/182

只有一个使用计算反应属性的例子:

export const computedMsg = computed(() => props.msg + '!!!')

由于当前没有提到&lt;scrip setup&gt; 的可用的Vuex 4 文档,我仍然不清楚在使用这种语法时我应该如何使用mapGetters?或者用 Vuex 4 解决这个问题的正确方法是什么?

【问题讨论】:

现在记录在案。您不需要使用 mapGetters。 next.vuex.vuejs.org/guide/… 【参考方案1】:

tldr:向下滚动到最终结果

现在有更好的文档,简单的答案是:您不需要mapGetters,但您可以自己实现。

https://next.vuex.vuejs.org/guide/composition-api.html#accessing-state-and-getters

<script setup>
import  computed  from 'vue'
import  useStore  from 'vuex'

const store = useStore()

const count = computed(() => store.getters.count)
</script>

如果你有很多 getter 想要变成“计算属性”,你可以使用像这样“直观”的东西:

const  countIsOdd, countIsEven  = Object.fromEntries(Object.keys(store.getters).map(getter => [getter, computed(() => store.getters[getter])]))

把它放到一个函数中,它甚至看起来不错。

const mapGetters = (getters) => 
  return Object.fromEntries(Object.keys(getters).map(getter => [getter, computed(() => getters[getter])]))


const  countIsOdd, countIsEven  = mapGetters(store.getters)

将该函数放入文件中并将其导出为模块...

// lib.js
import  computed  from 'vue'
import  useStore  from 'vuex'

const mapGetters = () => 
  const store = useStore()
  return Object.fromEntries(Object.keys(store.getters).map(getter => [getter, computed(() => store.getters[getter])]))


export  mapGetters 

...您可以轻松地在所有组件中使用它。

// components/MyComponent.vue
<script setup>
import  mapGetters  from '../lib'

const  countIsOdd, countIsEven  = mapGetters()
</script>

最终结果:

这是我想出的最终 lib.js:

import  computed  from 'vue'
import  useStore  from 'vuex'

const mapState = () => 
  const store = useStore()
  return Object.fromEntries(
    Object.keys(store.state).map(
      key => [key, computed(() => store.state[key])]
    )
  )


const mapGetters = () => 
  const store = useStore()
  return Object.fromEntries(
    Object.keys(store.getters).map(
      getter => [getter, computed(() => store.getters[getter])]
    )
  )


const mapMutations = () => 
  const store = useStore()
  return Object.fromEntries(
    Object.keys(store._mutations).map(
      mutation => [mutation, value => store.commit(mutation, value)]
    )
  )


const mapActions = () => 
  const store = useStore()
  return Object.fromEntries(
    Object.keys(store._actions).map(
      action => [action, value => store.dispatch(action, value)]
    )
  )


export  mapState, mapGetters, mapMutations, mapActions 

在组件中使用 this 看起来像这样:

<template>
  Count:  count 
  Odd:  counterIsOdd 
  Even:  counterIsEven 
  <button @click="countUp">count up</button>
  <button @click="countDown">count down</button>
  <button @click="getRemoteCount('https://api.countapi.xyz')">
    get remote count
  </button>
</template>

<script setup>
import  mapState, mapGetters, mapMutations, mapActions  from '../lib'

// computed properties
const  count  = mapState()
const  countIsOdd, countIsEvent  = mapGetters()

// commit/dispatch functions
const  countUp, countDown  = mapMutations()
const  getRemoteCount  = mapActions()
</script>

非常感谢您对此的任何反馈。

【讨论】:

我真的很喜欢这个解决方案,我正在调整它以使用命名空间模块,但我在陌生的水域......我已经想出了如何将模块名称添加到 mapState 函数,但我是没有任何运气让它工作 mapGetters...有什么想法吗? 更新:gist.github.com/ub3rb3457/586467f2cbd54d0c96d60e16b247d151 此版本允许您将模块名称作为参数传递给映射函数 嘿!很高兴这很有帮助。现在没有时间研究你的适应情况,但我一定会的!【参考方案2】:

到目前为止,这种语法似乎有效。不过,我希望 Vuex 能够开发出一种更简洁的方式来为模板公开计算的 getter。

如果您知道更好的方法,我们很乐意听到!

<script setup lang="ts">
import  mapGetters  from 'vuex';

export const name = 'MyCoolBareComponent';

export default 
  computed: 
    ...mapGetters('user', ['profile', 'roles']),
  ,
;
</script>

【讨论】:

以上是关于如何将 Vuex mapGetters 与 Vue 3 SFC 脚本设置语法一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Vuex mapGetters 时如何修复 TypeScript 错误?

使用 Vuex,为啥 mapGetters 不接受与 mapState 相同的语法?

使用Vue CDN时如何使用mapGetters?

Vuex 反应式 mapGetter 与传递的参数

Vuex mapGetter的基本使用

Vue技术-mapstart与mapGetters=》模块化+命名空间