Vuex中的辅助功能

时间:2020-06-11 16:27:26

标签: vue.js vuejs2 vuex

我是Vuejs的新手,但我来自React,只是想在这里使用Vuex。

我建立的商店的状态包含数组cart

const state = () => ({
    cart: []
})

我想要一个函数isInCart(product),该函数返回产品是否在当前购物车中。

<span v-if="isInCart(product)">hello</span>

我应该使用商店的获取器吗?

const getters = {
    isInCart: (state) => (product) => state.cart.find(_product => _product.id === product.id) !== undefined,
}

然后在我的组件中像这样使用它?

computed: {
    ...mapGetters(['isInCart'])
},

但是我有Computed property "isInCart" was assigned to but it has no setter.

编辑

我忘了给吸气剂加上模块名称。

...mapGetters({ isInCart: 'shop/isInCart' }) // module name = shop

2 个答案:

答案 0 :(得分:1)

Ref:我应该使用商店的获取器吗?

是的。 ...mapGetters({})仅从您的商店读取 getter

如果您想读取 state 属性(即cart),请使用

computed: {
  ...mapState({ cart })
}

...或

computed: {
  cart() {
    return this.$store.state.cart
  }
}

参考: Computed property "isInCart" was assigned to but it has no setter.

这是因为您正在尝试为要导入的组件内的isInCart分配一个值。

您不能那样做。如果您实际上想将商店吸气剂设置为特定值,请使用以下模式:

computed: {
  yourGetter: {
    get: function() {
      return this.$store.getters['yourGetter']
    },
    set: function(value) {
      this.$store.dispatch('actionCommittingMutationChangingYourGetter', value)
    }
  }
}

注意:如果您只需要该组件中的吸气剂,则不必是商店吸气剂。您可以直接从get state>:

computed: {
  whatever: {
    get: function() {
      return this.$store.state.whatever;
    },
    set: function(value) {
      this.$store.dispatch('setWhatever', value);
    }
  }
}

注意:如果您的getter返回一个函数(如您的情况),则可以在将其映射到组件中后按计算方式安全地调用它(即this.isInCart(product))。使用带参数的计算是不寻常的,但是如果它返回fn,则可以调用fn。

另一方面,在许多情况下,您可以直接跳过dispatchcommit。但是直接从商店外部进行提交不被认为是“安全的”,在某些情况下,这样做会出错。
从原则上讲,我建议不要这样做,尽管它在某些情况下确实可以工作。


请参阅如何编写fn清洁器。该讨论涉及许多个人喜好以及您或您的团队可能已经制定的编码标准。这使得关于Stack Overflow的讨论 se-se 成为关闭主题。

只是踢脚,这就是我的写法。但这不是因为它更好或更干净。它是基于纯粹的个人喜好,并且可能比您拥有的要快一些:

const getters = {
  isInCart: state => product => state.cart.map(p => p.id) 
    .findIndex(id => id === product.id) > -1
}

答案 1 :(得分:0)

看看以下Vuex getter的答案,该参数具有参数:Pass params to mapGetters

编辑

我同意,这并不干净也不简单。我宁愿重新设计:

选项1

您可以使用Vuex的购物车直接进行计算,并保持反应性:

<template>
  <span v-if="$store.state.cart.some(p => p.sku === productSku)">hello</span>
  <!—- both work efficiently —>
  <span v-if="hasProduct(productSku)">hello</span>

</template>
<script>
export default {
  methods: {
    hasProduct(sku) {
      return this.$store.state.cart.some(p => p.sku === sku)
    }
  }
}
</script>

话虽如此,这不是计算属性。您希望具有一个已计算属性的多个返回值,但并非为此目的而设计。

选项2

您最好的选择是引入与此组件相关的产品版本:

<template>
  <span v-if="hasProduct">hello</span>
<template>

<script>
export default {
  name: „ProductRelevantComponent“
  props: {
    productSku: {
      type: String,
      required: true
    }
  },
  computed: {
    hasProduct() {
      return this.$store.state.cart.some(p => p.sku === this.productSku)
    }
  }
}
</script>
相关问题