javascript - 更新时如何使vuex状态更新UI?

标签 javascript vue.js vuejs2 vue-component vuex

我正在使用 Vuejs 和 Vuex 构建购物车页面。购物车中的每个项目都应该有一个数量计数器来增加或减少为这个特定项目订购的件数。 当我从主产品页面将产品添加到购物车时,然后访问购物车页面。我点击柜台,产品数量发生了变化,但 UI 没有显示这一变化。它仅在我重新加载页面后显示更改,之后它只能显示对该特定计数器的任何新更改,并且我必须在添加每个产品后重新加载才能使其计数器显示 UI 更改。

这是简化的购物车 Vue 组件:

 <template >
    <tbody>
        <tr v-for="product in cartProducts" :key="product.name">
            <td class="quantity">
                <i class="fa fa-minus" @click="decreaseQuantity(product)"></i>
                <p>{{product.quantity}}</p>
                <i class="fa fa-plus" @click="increaseQuantity(product)"></i>
            </td>
        </tr>
    </tbody>
</template>

<script>
export default {
    computed: {
        cartProducts() {
            return this.$store.state.cartProducts;
        },
    },
    methods: {
        increaseQuantity(drug) {
            const existedDrug = this.cartProducts.find(d => d.id === drug.id);
            existedDrug.quantity += 1;
            this.$store.dispatch("setUserDataCart", this.cartProducts);
            console.log(this.$store.state.cartProducts);
        },
        decreaseQuantity(drug) {
            const existedDrug = this.cartProducts.find(d => d.id === drug.id);
            existedDrug.quantity -= 1;
            this.$store.dispatch("setUserDataCart", this.cartProducts);
            console.log(this.$store.state.cartProducts);
        },
    },
};
</script>

这是我的 vuex 商店:

import Vue from "vue";
import Vuex from "vuex";
import VuexPersist from "vuex-persist";

Vue.use(Vuex);
const vuexPersist = new VuexPersist({
  key: "my-app",
  storage: window.localStorage
});

const store = new Vuex.Store({
  state: {
    cartProducts: []
  },
  mutations: {
    SET_USER_CART(state, data) {
      state.cartProducts = data;
    }
  },
  actions: {
    setUserDataCart({ commit }, data) {
      commit("SET_USER_CART", data);
    }
  },
  plugins: [vuexPersist.plugin]
});

export default store;

我尝试了多种方法,例如使用 mapState 或将状态用作 getter 但没有成功。 谁能确定我做错了什么?

最佳答案

Vue.js docs :

Computed properties are by default getter-only

您尝试在没有 set method 的情况下更改计算属性的方式. 可能发生的情况是,仅更改对象属性而不创建新属性可能不会触发更新 UI 的 react 。

我实际上建议采用另一种方法并将逻辑移动到商店的变异方法,只传递您需要递增/递减的产品的 ID。并且还使用一种在更新后返回全新对象的方法(比如我用来更改 cartProductsmap() 方法。

store.js:

import Vue from "vue";
import Vuex from "vuex";
import VuexPersist from "vuex-persist";

Vue.use(Vuex);
const vuexPersist = new VuexPersist({
  key: "my-app",
  storage: window.localStorage
});

export default new Vuex.Store({
  state: {
    cartProducts: [
      {
        id: 1,
        name: "Drug 1",
        quantity: 1
      },
      {
        id: 2,
        name: "Drug 2",
        quantity: 1
      }
    ]
  },
  mutations: {
    INCREMENT(state, productId) {
      state.cartProducts = state.cartProducts.map(product => {
        if (product.id === productId) {
          product.quantity += 1;
        }
        return product;
      });
    },
    DECREMENT(state, productId) {
      state.cartProducts = state.cartProducts.map(product => {
        if (product.id === productId) {
          product.quantity -= 1;
        }
        return product;
      });
    }
  },
  actions: {
    incrementQuantity({ commit }, productId) {
      commit("INCREMENT", productId);
    },
    decrementQuantity({ commit }, productId) {
      commit("DECREMENT", productId);
    }
  },
  plugins: [vuexPersist.plugin]
});

购物车.js

<template>
  <table>
    <tbody>
      <tr v-for="product in cartProducts" :key="product.name">
        <td class="quantity">
          <button @click="decreaseQuantity(product)">decrease</button>
          <p>{{ product.quantity || 0 }}</p>
          <button @click="increaseQuantity(product)">increase</button>
        </td>
      </tr>
    </tbody>
  </table>
</template>

<script>
export default {
  computed: {
    cartProducts() {
      return this.$store.state.cartProducts;
    }
  },
  methods: {
    increaseQuantity(drug) {
      this.$store.dispatch("incrementQuantity", drug.id);
    },
    decreaseQuantity(drug) {
      this.$store.dispatch("decrementQuantity", drug.id);
    }
  }
};
</script>

关于javascript - 更新时如何使vuex状态更新UI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60788909/

相关文章:

javascript - Mootools Request() 每个 session IE9 只工作一次

vue.js - Vuetify.js - <v-menu> 内的 <v-text-field> 没有 <v-menu> 消失就无法聚焦

javascript - VueJS 有条件地为元素添加一个属性

javascript getAttribute() 在 iPad2 Safari 上不起作用

javascript - 测试异步函数的问题

javascript - Vue 相当于 setTimeout?

vue.js - vuex 如何像 redux 一样改变商店中的多个属性?

javascript - 使用组合 API 插件的 Vue 2 中功能组件(同时正常工作)的未定义监听器错误

javascript - 如何在Vue中特定组件的范围内定义 `setInterval`?

javascript - 在文本区域中将 <br> 替换为\n 在 IE9 中不起作用