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>
我在 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>