0👍
Use computed properties:
computed: {
filteredItems(){
if(this.selectedCategory.length == 0) return this.items;
return this.items.filter(el => {
for(let i = 0; i < this.selectedCategory.length; i++){
if(el.categories == this.selectedCategory[i]) return el;
}
});
}
}
Then you go for v-for="item of filteredItems"
I didnt tested it. If you provide me more code i could help you more
0👍
You need to create one-way
binding between your CategoryCheckBox
component and your ListCard
component.
Because you provided separated code when I can not reproduce it to give you a solution based on your own, I suggest this example to explain my solution.
Step One:
You have many ways to CRUD your items
using a Plugins or Vuex or global instance, in my example I used global instance in main.js
Vue.prototype.$myArray = ["Books", "Magazines", "Newspaper"];
I assume you created your items
data in the ListCards
component
Step Two:
You need to add @change
event in your checkbox
to handle checked
and unchecked
states. I used static data (Book) for value
.
<label>
<input type="checkbox" value="Books" @change="handleCategory($event)" /> Books
Now, let’s implement handleCategory
method, but before that, as we know that Checkbox
and ListCards
are independents which means we need to define a bus
to create event
communication between them and this is your issue so we define the bus
inside the main.js
Vue.prototype.$bus = new Vue({});
Now we define handleCategory
like this :
methods: {
handleCategory(e) {
this.$bus.$emit("checkCategory", e);
}
}
Step Three:
How can our ListCards
listen to this event
?
By call $bus.$on(..)
when the component is created
( Hope you know what Vue lifecycle methods mean )
created() {
this.$bus.$on("checkCategory", e => this.checkCategory(e));
},
When the user click the check box the component runs handleCategory
then runs checkCategory
inside ListCard
.
Inside my ListCard, I have categories
and originalCategories
as data
data() {
return {
categories: this.$myArray,
originalCategories: this.$myArray
};
},
and a template :
<ul v-for="(category,index) in categories" :key="index">
<CategoryItem :categoryName="category" />
</ul>
and a created
method ( lifecycle )
created() {
// $bus is a global object to communicate between components
this.$bus.$on("checkCategory", e => this.checkCategory(e));
},
and our filtering methods :
methods: {
checkCategory(e) {
let target = e.target;
let value = e.target.value;
target.checked
? this.filterCatergories(value)
: (this.categories = this.originalCategories);
},
filterCatergories(value) {
this.categories = this.categories.filter(val => val === value);
}
}
What’s important for you is :
this.categories.filter(val => val === value); //will not do nothing
const categories=this.categories.filter(val => val === value); //will update the view.
And you can change the code or make it better and simple.
@Update
You can also use computed properties but because we have a parameter here which is the category name we need get
and set
.
computed: {
filteredItems: {
get: function() {
if (this.selectedCategory.length == 0) return this.items;
return this.items.filter(value => {
for (const category of this.selectedCategory) {
if (value == category) return value;
}
});
},
set: function(category) {
this.selectedCategory.push(category);
}
}
},
methods: {
checkCategory(e) {
let target = e.target;
let value = e.target.value;
target.checked
? (this.filteredItems = value)
: this.selectedCategory.pop(value);
}
}