上下文:
我第一次在项目中使用VueJS,所以我可能没有正确使用它。
我有一个 parent 和一个 child 组成部分:
父类别:ResearchProducts.vue:显示可以按类别筛选的产品列表。过滤器是与产品类别相关的复选框。
子级:CategoryDisplay.vue:这是处理 View 和类别行方法的组件。
我的问题:
当我单击子组件内部的类别复选框时,如果该复选框被选中,则类别将添加到父组件的过滤器列表中。这行得通。
当我取消选中该复选框时,该类别将从此列表中删除。这也可以。
现在,我已将所有类别显示为父组件中的按钮,以使用户更容易看到过滤器。我的问题是,当我单击该按钮时,我希望此按钮取消选中子组件内部的相关复选框。
这是我的实际代码:
ResearchProducts.vue:
<template>
<div>
<template v-for="category in categories">
<category-display
:category="category"
:key="'category_'+category.id"
:checked="checked"
@categorySelected="categorySelected"
></category-display>
</template>
<button
v-for="filter in listFilters"
:key="'filter_'+filter.slug"
class="btn btn-light btn-sm mr-2 mb-2"
@click="removeFilter(filter)"
>
{{ filter.name }}
</button>
</div>
</template>
<script>
export default {
data() {
return {
categories: { // HERE A COLLECTION CONTAINING ALL MY CATEGORIES },
selectedCategories: [],
listFilters: []
};
},
methods: {
categorySelected(category) {
var newCategory = {
type: "category",
slug: category.slug,
name: category.name
};
if (category.checked) {
if (!this.selectedCategories.includes(category.slug)) {
this.selectedCategories.push(category.slug);
this.listFilters.push(newCategory);
}
} else {
if (this.selectedCategories.includes(category.slug)) {
const index = this.selectedCategories.indexOf(category.slug);
if (index > -1) {
this.selectedCategories.splice(index, 1);
}
}
this.listFilters = this.listFilters.filter(function(item) {
for (var key in newCategory) {
if (item[key] === undefined || item[key] == newCategory[key])
return false;
}
return true;
});
}
},
removeFilter(filter) {
// THERE, I NEED TO UNCHECK THE RELATED CHECKBOX IN CHILD COMPONENT
this.listFilters = this.listFilters.filter(function(item) {
for (var key in filter) {
if (item[key] === undefined || item[key] == filter[key]) return false;
}
return true;
});
}
}
};
</script>
CategoryDisplay.vue:
<template>
<b-form-checkbox-group class="w-100">
<b-form-checkbox :value="category.slug" class="w-100" @input="selection" v-model="selected" ref="checked">
{{ category.name }}
<span class="badge badge-secondary float-right">{{ category.products_count }}</span>
</b-form-checkbox>
</b-form-checkbox-group>
</template>
<script>
export default {
props: {
category: {
type: Object,
required: true
}
},
data() {
return {
selected: false
}
},
methods: {
selection() {
var response = false;
if(this.selected.length !== 0){
response = true;
}
this.$emit('categorySelected', {slug: this.category.slug, name: this.category.name, checked: response});
}
}
};
</script>
最佳答案
这是一个简化的示例,供您引用。您可以使用sync
修饰符在父级和子级之间实现双向绑定(bind)。这与子项中的setter
和getter
的计算属性一起
因此,将所有类别传递给子类别,并同步所选类别:
<HelloWorld :cats.sync="selectedCategories" :categories="categories"/>
子组件采用类别,进行迭代并显示复选框。在这里,我们使用计算属性,单击复选框时,
setter
将更改发送给父级:<label v-for="c in categories" :key="c.id">
<input v-model="temp" type="checkbox" :value="c">
{{ c.name }}
</label>
脚本:
computed: {
temp: {
get: function() {
return this.cats;
},
set: function(newValue) {
this.$emit("update:cats", newValue);
}
}
}
父级只是简单地迭代
selectedCategories
,而您希望的是,当父级selectedCategories
发生更改时,子级将自动知道何时删除项目。以下是完整的示例供您引用:SANDBOX