简体   繁体   English

更新 Vuex 商店 state 上的 DOM 更改

[英]Update DOM on Vuex store state change

I have an 'Add To Basket' button which triggers a Vuex store action:我有一个触发 Vuex 商店操作的“添加到购物篮”按钮:

<button
  @click="addToBasket(item)"
>
  Add To Basket
</button>

Vuex store: Vuex商店:

const actions = {
    addToBasket({ commit }, item) {
        commit("setBasketItems", item);
    }
};

const mutations = {
    setBasketItems: (state, item) => {
        let basketFind = state.basket.find(i => {
            return i.id === item.id;
        });

        if (basketFind) {
            basketFind.quantity += 1;
            return;
        }

        item.quantity = 1;

        state.basket.push(item);
    }
};

const state = {
    basket: []
};

const getters = {
    basketItems: state => state.basket,
};

When I check the Vuex store in dev tools it's doing what it should, ie adding the item if it doesn't exist, incrementing the quantity if it does.当我在开发工具中检查 Vuex 商店时,它正在做它应该做的事情,即如果它不存在则添加该项目,如果它存在则增加数量。

I'm trying to update the DOM to display the item's quantity:我正在尝试更新 DOM 以显示项目的数量:

computed: {
  computedBasketItems: function() {
    return this.$store.getters.basketItems;
  }
},
<CartItem
  v-for="item in computedBasketItems"
  :key="item.id"
  :item="item"
/>

CartItem (accepting the item as a prop): CartItem(接受该项目作为道具):

<div class="dropdown-item">
  <i class="fa fa-times-circle"></i>
  <router-link to="">{{ item.name }}</router-link>
  <p>{{ item.quantity }}x</p>
  <p>{{ item.price }}</p>
</div>

// props...
    props: ["item"],

It adds the item to the DOM and sets the quantity to '1' but doesn't update the quantity whenever it changes.它将项目添加到 DOM 并将数量设置为“1”,但不会在数量发生变化时更新数量。

How can I do this?我怎样才能做到这一点?

  const mutations = {
    setBasketItems: (state, item) => {
      // in this line we checking if item id equal state backet item id it returns first matched element 
      let basketFind = state.basket.find((i) => {
        return i.id === item.id;
      });

      // here we checking if basketFind has value(aka array contains value) 
      if (basketFind) {

        // if basketFind is true in this case will be implement this block
        state.basket = state.basket.map((x) =>
          x.id === item.id ? { ...x, quantity: x.quantity + 1 } : x
        );

        // in this line we reassigning basket prop of state with transformed data
        // just checking if  x.id === item.id then increase matched element's prop quantity  
        // also we leave other elements which contains state.basket array
        return;

      }
      // if basketFind is false we going this line
      // again, reassigning basket prop of state. adding existing element and adding new element with value 1 of quantity prop
      state.basket = [
        ...state.basket,
        ...[item].map((x) => ({ ...x, quantity: 1 })),
      ];
    },
  };

The reason is that your items you are adding are not reactive.原因是您添加的项目不是反应性的。 only your basket array is reactive.只有你的篮子阵列是反应性的。 and adding Item to It will re-render.并将 Item 添加到它将重新渲染。 but you are just pushing the Item, and if you change the Item's property its not reactive.但您只是在推动项目,如果您更改项目的属性,它不会反应。 to do that use Vue.$set(basketFind,'quantity',basketFind.quantity+1) in place of basketFind.quantity += 1;为此,请使用Vue.$set(basketFind,'quantity',basketFind.quantity+1)代替 basketFind.quantity += 1;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM