Removing and Filtering
Habits change: one you've stopped doing should go, and on a busy day, you'll want to see only what's left to do. In this exercise, each habit gets a Remove button, and the list gets a filter.
Removing. The button is in HabitItem, but the habits are in App.vue, so it's just like the checkbox: the component sends an event, this time remove, and the parent does the work. A component can send several events, and defineEmits lists them all:
const emit = defineEmits(["toggle", "remove"]);
<button @click="emit('remove', habit.id)">Remove</button>
The button goes after the label, not inside it, because the label belongs to the checkbox. In App.vue, remove(id) keeps all the habits except that one, with filter(). It makes a new array, which goes into habits.value, as in the lesson State and Events:
function remove(id) {
habits.value = habits.value.filter((habit) => habit.id !== id);
}
Filtering. Above the list, a drop-down list (a select) chooses what the list shows: all the habits, only the ones still to do, or only the done ones. v-model puts its value into the ref filter, and the list shows a computed value made from habits and filter. (The ref filter and the array method filter() only share a name.)
<label class="filter">
Show
<select v-model="filter">
<option value="all">All</option>
<option value="todo">To do</option>
<option value="done">Done</option>
</select>
</label>
const filter = ref("all");
const shownHabits = computed(() => {
if (filter.value === "todo") {
return habits.value.filter((habit) => !habit.done);
}
if (filter.value === "done") {
return habits.value.filter((habit) => habit.done);
}
return habits.value;
});
The progress still counts all the habits, from habits. Only v-for goes through shownHabits. With the filter on To do, a habit you check off leaves the list at once, because it's no longer in shownHabits.
Instructions
- 1
In
HabitItem.vue, add"remove"todefineEmitsand put the button from above after thelabel. InApp.vue, writeremove(id)and add@remove="remove"toHabitItem. Remove a habit: it disappears, and the progress counts one habit fewer. - 2
Add the ref
filterand the computed valueshownHabitsfrom above, put thelabelwith the select above the list, and changev-forso that it goes throughshownHabits. Check a habit off and choose To do: the habit isn't in the list. Choose Done, and it's the only one there.