vue.js 无法获取mutator逻辑以正确地将适当数量的项目添加到购物车中

5ssjco0h  于 2023-01-31  发布在  Vue.js
关注(0)|答案(2)|浏览(106)

我正在尝试创建一个add to cart函数,该函数首先检查要添加的项目是否已经在购物车中。如果在购物车中,则更新其quantity属性。如果不在购物车中,则将整个对象添加到购物车中。我认为我的问题是我的"ADD_ITEM_TO_CART"赋值函数内部的逻辑错误。
这是我的商店,其中包含我单击"addToCart()"时的一些console. logs()

state: {
    checkoutCart: [],
  },

actions: {
  cartAdd({ commit }, payload) {
      commit("ADD_ITEM_TO_CART", payload);
   },
 },

mutations: {
    ADD_ITEM_TO_CART(state, payload) {
          //CONSOLE.LOG()'s
          console.log("state.checkoutCart[0]", state.checkoutCart[0]);
          // eslint-disable-next-line
          console.log("state.checkoutCart[0].item", state.checkoutCart.item);
          console.log("state.checkoutCart", state.checkoutCart);

          //IF ITEM ALREADY IN checkoutCart, UPDATE IT'S QUANTITY
          if (state.checkoutCart.includes(payload.item)) {
            state.checkoutCart.quantity += payload.quantity;
            console.log("Item already in cart");
          } 
          //IF ITEM NOT IN checkoutCart, UPDATE THE QUANTITY PROPERTY AND ADD ITEM TO CART
          else {
            payload.item.quantity = payload.quantity;
            state.checkoutCart.push(payload);
          }

https://i.imgur.com/rjOOljN.png
我以为这段代码可以工作,但它总是执行ELSE条件并像
if(声明. checkoutCart.包括(有效负载.项目))
根本就没有被识别或工作。
https://i.imgur.com/LLB790Z.png
VueX devtools显示了同样的东西,一个"item"对象在一个数组中的一个对象中。
我也试过:

ADD_ITEM_TO_CART(state, payload) {
  console.log("add_item_to_cart"); <---ONLY PART THAT SHOWS UP IN CONSOLE.LOG() WHEN EXECUTED

  //LOOP THROUGH ALL ARRAY ENTRIES TO GAIN ACCESS TO state.checkoutCart.item 
  for (let i = 0; i < state.checkoutCart.length; i++) {
    console.log("i=", i);
    console.log("state.checkoutCart.item", state.checkoutCart.item);

    //IF ITEM ALREADY IN checkoutCart, UPDATE IT'S QUANTITY
    if (state.checkoutCart[i].item.includes(payload.item)) {
      state.checkoutCart.quantity += payload.quantity;
      console.log("Item already in cart");
      return;
    }; 
  }
  //IF ITEM NOT IN checkoutCart, UPDATE THE QUANTITY PROPERTY AND ADD ITEM TO CART 
  payload.item.quantity = payload.quantity;
  state.checkoutCart.push(payload);
},

因为我想我需要遍历所有的数组条目,但是for循环根本就没有运行,而且在这段代码中,根本就没有东西被添加到购物车中。
我不知道我做错了什么。有人能帮我吗?我的语法错了吗?或者我的逻辑错了吗?我访问数组/对象的方式不正确吗?我如何正确地编写"ADD_ITEM_TO_CART"赋值函数?我已经花了一整天的时间在这上面,我的大脑都要关闭了。
编辑:
https://i.imgur.com/bkU8YSo.png

    • 有效载荷**
<div v-for="item in items">  <--ACTUALLY PROP FROM PARENT COMPONENT BUT SAME IDEA
          <p>
            Qty
            <select v-model="quantity">
              <option value="1">1</option>
              <option value="2">2</option>
              <option value="3">3</option>
            </select>
          </p>
          <p>
            <button type="button" @click="addToCart()">
              Add to Cart
            </button>
          </p>
        </div>

let quantity = ref("1");
const addToCart = () => {
  console.log("addToCart Running");
  store.dispatch("cartAdd", { item: item.value, quantity: quantity.value });
};
nwnhqdif

nwnhqdif1#

这是因为if条件没有检查你的想法。
Array.prototype.includes检查数组中是否有值,但有两种情况:

  • 值是主类型(字符串、数字、布尔值...)。它按值进行比较。
  • 这个值是一个对象。然后**它通过引用进行比较。

所以这里,你要检查item对象的引用是否已经包含在数组中,但是没有,因为它是一个新对象。
解决方法:检查是否有相同值的对象,而不是引用。
可以使用some方法,但必须编写一个条件来检查两项是否相等。
下面是一个项目具有ID的示例:

if (state.checkoutCart.some(item => item.id === payload.item.id))
uujelgoq

uujelgoq2#

问题确实出在ADD_ITEM_TO_CART变异内部。
正如Kapcash所指出的,具有相同属性和相同值的两个对象是不相同的。
换句话说,.includes()检查的是同一性,而不是相等性。为了更好地理解这一点,请考虑以下示例:

const a = { foo: 'bar' }
const b = [{ foo: 'bar' }]
const c = [a]
const d = [{ ...a }]

console.log(b.includes(a)) // false
console.log(c.includes(a)) // true
console.log(d.includes(a)) // false

要克服这一点,请使用Kapcash的答案。
我只想提一下,处理这个问题的标准方法是在对象上使用唯一标识符(例如:流体)。
一旦你解决了以上问题,它仍然不会工作,因为你会遇到以下问题:在if中,您试图更改state.checkoutCartquantity。并且数组没有quantity属性。
实现所需功能的正确逻辑是(假设checkoutCart成员的唯一标识符是item._id,根据您发布的图片):

ADD_ITEM_TO_CART(state, payload) {
  // find the index of a cart element having same `item._id` value as the payload
  const index = state.checkoutCart.findIndex(
    (el) => el.item._id === payload.item._id
  )
  if (index > -1) {
    // if the index is higher than `-1`, an element was found
    // create a copy, update its quantity and then 
    // replace the original element with the copy
    const copy = { ...state.checkoutChart[index] }
    copy.quantity += payload.quantity
    state.checkoutCart.splice(index, 1, copy)
  } else {
    // no element found, add payload to `checkoutCart`
    state.checkoutCart.push(payload)
  }
}

旁注:你的item不应该包含quantity属性。这是购物车的责任,而不是项目的。通过将其添加到item,你最终会得到两个需要保持同步的事实来源。你不希望出现这种问题。

相关问题