【问题标题】:Returning arrow function from Vuex storage getter: Not understanding从 Vuex 存储获取器返回箭头函数:不理解
【发布时间】:2019-01-18 18:08:13
【问题描述】:

我一直在观看一门 Vuex 课程,直到现在一切都很好,直到他们在 getter 中包含箭头函数,然后在计算属性和操作中使用它。代码如下:

项目结构:

const _products = [
  { id: 1, title: "iPad 4 Mini", price: 500.01, inventory: 2 },
  { id: 2, title: "H&M T-Shirt White", price: 10.99, inventory: 10 },
  { id: 3, title: "Charli XCX - Sucker CD", price: 19.99, inventory: 5 }
];

store.js 中的吸气剂:

    productIsInStock() {
      return product => {
        return product.inventory > 0;
      };
    }

store.js 中使用此 getter 的操作:

    addProductToCart(context, product) {
      if (context.getters.productIsInStock(product)) {
        let cartItem = context.state.cart.find(item => item.id === product.id);
        if (!cartItem) {
          context.commit("pushProductToCart", product.id);
        } else {
          context.commit("incrementItemQuantity", cartItem);
        }
        context.commit("decrementProductInventory", product);
      }
    },

使用此 getter 和模板的计算,ProductList.vue

<template>
            <li v-for="(product, index) in products" v-bind:key="index">
                {{product.title}} - {{product.price | currency}} - {{product.inventory}}
                <button
                    @click="addProductToCart(product)"
                    :disabled="!productIsInStock(product)"
                >
                    Add product to cart
                </button>
            </li>
</template>
  // ...

  computed: {
    products() {
      return this.$store.state.products;
    },
    productIsInStock() {
      return this.$store.getters.productIsInStock;
    }
  },

完全工作,但我不明白为什么。主要是我不明白这个 getter 在计算和 if 语句中是如何工作的。我试图在控制台中重复相同的结构,但由于某种原因它根本不起作用。希望我提供了足够的代码

【问题讨论】:

  • 也许不清楚不清楚什么,但该函数需要product,检查其是否为@987654329 @ 大于 0,并返回结果 - truefalse。如果有帮助的话,你可以把它想象成productIsInStock = (product) =&gt; product.inventory &gt; 0;
  • @TylerRoper 我不清楚:1)getter 中的箭头函数如何获取值,不只是参数的名称吗? 2)正如我在控制台中看到的,这个getter返回函数我不明白它在if语句中是如何工作的,无论我使用什么具有库存属性的模拟对象,控制台总是返回true,但在控制台之外它工作得很好.我知道这个 getter 过滤结果,但我不明白从语法的角度会发生什么。

标签: javascript vue.js vuex getter arrow-functions


【解决方案1】:

让我看看我是否理解你的疑问。

productIsInStock 是一个 getter,它返回一个箭头函数,vue 通过模板部分在渲染函数中评估它:

<button
     @click="addProductToCart(product)"
     :disabled="!productIsInStock(product)">
       Add product to cart
</button>

首先要了解 vue 是很重要的,这要归功于 :disable databind,它会将值评估为 javascript。所以它计算getter的实际值(即一个函数),然后你调用实际返回值(记住,是一个函数)返回一些东西。

换一种说法:每次相关状态发生变化时都会调用 getter,以重新计算值,这就是为什么您使用 getter(如 this.getterA + this.getterB)而不是调用 getter(如 this.getterA() this.getterB())。

如果还是不明白,请查看我的替换模板渲染的“假”渲染函数:

let productIsInStock = () => product => { ... }

render(h) {
 return h('button', {
   '@click': () => this.addProductToCard(product),
   ':disabled': () => productIsInStock()(product), // using arrow fn instead of the getter
 }
}

这在函数式编程语言中也称为柯里化。

【讨论】:

  • 谢谢,非常有帮助,现在我了解它在模板中的工作方式,但仍然不知道它在 if statement 中的工作方式。据我所知,它不会变成productIsInStock()(product)。那么,if(store.getters.productIsInStock(product)) 如何将产品参数转换为它返回的箭头函数?当我尝试仅调用 store.getters.productIsInStock({inventory: 5}) 时,它会返回该函数,但是一旦我将其包装到另一个函数中,例如 function foo(product) { if(store.getters.productIsInStock(product)) { console.log(product); } } 它就可以正常工作
  • 因为 this.$store.getters.productIsInStock 是一个 vue 创建的 es6 getter,而不是 store.getters.productIsInStock 中的原始函数,我想。
  • 是的,似乎是这样。我试图创建一个具有相同结构的对象,store.getters.productIsInStock 返回对返回箭头函数的函数的引用,而具有store.getters.productIsInStock 的实际 Vuex 存储对象返回箭头函数本身或对其的引用。因此,对于我自己的对象,我必须使用 store.getters.productIsInStock()(product),但对于实际的 Vuex 存储对象 store.getters.productIsInStock(product) 就可以了。我想我只是不明白这背后的机制......
  • 好的。我刚刚阅读了什么是 ES6 getter,现在我完全明白了。 Vuex getter 有 es6 getter,当我提到 getter 的名称时,实际返回值是 return 后面的内容。所以。 context.getters.productIsInStock(product) 通过 es6 getter 返回箭头函数,然后调用返回的函数。我认为我一直在观看的课程没有注意到关于 getter 如何在更低级别上实际工作的任何事情。谢谢!
【解决方案2】:

您将商店中的 getter 定义为一个函数。此函数与状态、其他 getter 一起调用(在模块的情况下,还有根状态和根 getter)。基于此,您返回一些值。通常,该数据是一些值(例如对象、数字、布尔值等)

getters: {
  numberOfPolarBears (state) {
    return state.polarBears.length;
  }
}

javascript 中的函数与其他数据没有太大区别。像这样的函数也可以定义为一些变量。

// Method 1
function ticklePolarBear (bear) {
  bear.tickle();
}

// Method 2
var ticklePolarBear = function (bear) {
  bear.tickle();
};

在任何一种情况下,您都可以这样称呼它:

ticklePolarBear(frostyTheBear);

为什么这很重要?当您通常映射一个 getter 并以这种方式取回一些数据时,没有什么能阻止您映射一个 getter 并返回一个您可以稍后调用的函数。

getters: {
  namedPolarBear (state) {
    return function (index) {
      if (index >= state.polarBears.length) {
        return null;
      }

      return state.polarBears[index].name;
    }
  }
}

箭头函数设置this的上下文不同,但在其他方面与上面的示例非常相似。


computed 在组件中为某些属性提供(在这种情况下)getter 函数。在您的示例中,它返回您商店中的 getter 返回的内容,即一个函数。既然是函数,就可以调用它。

在这种情况下,没有反应发生,因此您也可以编写以下内容:

data () {
  return {
    productIsInStock: this.$store.getters.productIsInStock
  };
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    • 2020-07-30
    • 1970-01-01
    相关资源
    最近更新 更多