Vue 组件不会重新加载 getter 数据(非反应性)

Vue component doesn't reload with getter data (not reactive)

我在 Vue 和 Vuex 中有这个电子商务模拟应用程序。此页面显示了 phone 的列表,并且有一个过滤器可以通过复选框根据 phone 品牌过滤 phone。

问题是在我点击复选框进行筛选后页面没有立即刷新。如果我单击另一个页面并单击返回原始页面,则该页面会被过滤。

这是我的源代码。为简洁起见,删除了一些代码。

Product.vue

import { mapActions } from "vuex";
import BrandFilter from "../components/BrandFilter";

export default {
  data() {
    return {
      products: this.$store.getters.filterProducts
    };
  },
  components: { BrandFilter }
};
<template>
  <div class="container">
    <div class="row">
      <div class="col-lg-3"><BrandFilter></BrandFilter></div>
      <div class="col-lg-9">
        <div class="row">
          <div v-for="product in products" :key="product.id">            
                <h4 class="card-title product__title">
                  {{ product.title }}
                </h4>                            
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

BrandFilter.vue

export default {
  name: "BrandFilter",
  data() {
    return {
      brands: this.$store.state.brands
    };
  },
  methods: {
    onChangeSelectBox(e) {
      debugger;
      const name = e.target.name;
      const value = e.target.checked;
      if (value) {
        this.$store.commit("addBrandToFilter", name);
      } else {
        this.$store.commit("removeBrandFromFilter", name);
      }
    }
  }
};
<template>
  <div class="card mb-3">
    <div class="card-header">
      <h3>Brands</h3>
    </div>
    <ul class="list-group flex-row flex-wrap">
      <li class="list-group-item flex-50" v-for="brand in brands" :key="brand">
        <label class="custom-checkbox text-capitalize">
          {{ brand }}
          <input
            type="checkbox"
            :name="brand"
            class="custom-checkbox__input"
            @input="onChangeSelectBox($event)"
          />
          <span class="custom-checkbox__span"></span>
        </label>
      </li>
    </ul>
  </div>
</template>

store/index.js

import Vue from "vue";
import Vuex from "vuex";
import { phones } from "../data/phones";
import { brands } from "../data/brands";
import { brandFilter } from "../filters/brandFilter";

Vue.use(Vuex);

export default new Vuex.Store({
  strict: true,
  state: {
    products: phones,
    brands: brands,
    cart: [],
    brandFilter: ""
  },
  getters: {
    filterProducts(state) {
      debugger;
      const brands = state.brandFilter;
      const filterByBrandArr = brandFilter(state.products, brands);
      return filterByBrandArr;
    }
  },
  mutations: {    
    addBrandToFilter: (state, brand) => {
      debugger;
      if (state.brandFilter.includes(brand)) return void 0;

      state.brandFilter += brand;
    },
    removeBrandFromFilter: (state, brand) => {
      debugger;
      const reg = new RegExp(brand, "gi");
      state.brandFilter = state.brandFilter.replace(reg, "");
    }
  }
});

当您将数据项设置为 Product.vue 中的 getter 时,它只会被分配一次。如果 getter 改变,数据不会随之改变:

data() {
  return {
    products: this.$store.getters.filterProducts  // ❌ Incorrect
  }
}

使用计算而不是 mapGetters 来保持组件数据与 Vuex 数据同步:

import { mapGetters } from 'vuex';
computed: {
  ...mapGetters(['filterProducts'])  // ✅ Correct
}

更改您的模板以使用计算得出的:

<div v-for="product in filterProducts" :key="product.id">            
   <h4 class="card-title product__title">
      {{ product.title }}
   </h4>                            
</div>