6

我正在将组件从常规 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 迁移文档SFC Composition API Syntax Sugar (<script setup>),链接到这个 RFC 页面:https ://github.com/vuejs/rfcs/pull/182

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

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

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

4

4 回答 4

4

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

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

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

export const name = 'MyCoolBareComponent';

export default {
  computed: {
    ...mapGetters('user', ['profile', 'roles']),
  },
};
</script>
于 2020-09-25T16:11:10.603 回答
3

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>

如果您有许多想要变成“计算属性”的吸气剂,您可以使用“直观”的东西,如下所示:

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>

对此的任何反馈将不胜感激。

于 2021-08-04T15:26:27.607 回答
0

你可以做这样的事情

import { mapGetters } from "vuex"
setup() {
  return {
    ...mapGetters("myModule", ["doSomething"])
  }
}
于 2022-02-08T05:25:10.770 回答
0

您无需导出任何内容,SFC 将为您注册所有变量和组件,并在template.

SFC 自动从文件名推断组件的名称。

以下是一些可能有用的示例:

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

import MyComponent from './components/MyComponent'

const store = useStore()

const data = 'Random string as a data'

// without module/data 
const myAction = () => store.dispatch('myAction')
// with data
const mySecondAction = () => store.dispatch('mySecondAction', data)

// with module
const myMutation = () => store.commit('moduleName/myMutation')
// with module/data
const myNewMutation = () => store.commit('moduleName/myNewMutation', data)

const myStateVariable = computed(() => store.state.myStateVariable)
// with module
const myGetter = computed(() => store.getters.moduleName.myGetter)

// replace using of mapState/mapGetters
const state = computed(() => store.state)

// and then
console.log(state.myStateVariable)
console.log(state.mySecondStateVariable)
....

</script>
于 2022-01-26T18:39:11.993 回答