从 Vuex 存储返回箭头函数getter:没看懂

Returning arrow function from Vuex storage getter: Not understanding

我一直在看一个 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 }
];

一个 getter 在 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 语句中是如何工作的。我试图在控制台中重复相同的结构,但由于某种原因它根本不起作用。希望我提供了足够的代码

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

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 和 return 稍后可以调用的函数。

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

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

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


组件中的

computed 为某些属性提供(在本例中)getter 函数。在您的示例中,它 return 是您商店中 getter 的 return,即函数。既然是函数,就可以调用。

在这种情况下没有反应,所以你也可以这样写:

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

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

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

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

重要的是首先要了解 vue,感谢 :disable databind,将值评估为 javascript。所以它计算 getter 的实际值(这是一个函数),你调用实际的 return 值(记住,是一个函数)return 东西。

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

如果还有不明白的,查看我的"fake"替代模板渲染的渲染函数:

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

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

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