Reputation: 3
I'm following this tutorial, where they point out a small bug with the checkbox status of forgetting the state of the ticked/unticked which can be solved by using the computed property.
I would like to ask, even if the attribute isDone
in Data (ToDoItem.vue
) has been changed to true
(by ticking the checkbox), why the box is still unticked
after clicking edit then cancel, and why computed property could solve this bug.
Below are parts of the scripts.
ToDoItem.vue
<template>
<div class="stack-small" v-if="!isEditing">
<div class="custom-checkbox">
<input
type="checkbox"
class="checkbox"
:id="id"
:checked="isDone"
@change="$emit('checkbox-changed')"
/>
<label :for="id" class="checkbox-label">{{ label }}</label>
</div>
<div class="btn-group">
<button
type="button"
class="btn"
ref="editButton"
@click="toggleToItemEditForm"
>
Edit <span class="visually-hidden">{{ label }}</span>
</button>
<button type="button" class="btn btn__danger" @click="deleteToDo">
Delete <span class="visually-hidden">{{ label }}</span>
</button>
</div>
</div>
<to-do-item-edit-form
v-else
:id="id"
:label="label"
@item-edited="itemEdited"
@edit-cancelled="editCancelled"
></to-do-item-edit-form>
</template>
<script>
import ToDoItemEditForm from "./ToDoItemEditForm";
export default {
components: {
ToDoItemEditForm,
},
props: {
label: { required: true, type: String },
done: { default: false, type: Boolean },
id: { required: true, type: String },
},
data() {
return {
isEditing: false,
isDone: this.done, // after deleting this line and use
//computed: {} below, the bug is solved.
};
},
// computed: {
// isDone() {
// return this.done;
// },
// },
};
</script>
ToDoItem.vue
<template>
<div id="app">
<h1>To-Do List</h1>
<to-do-form @todo-added="addToDo"></to-do-form>
<h2 id="list-summary" ref="listSummary" tabindex="-1"> {{ listSummary }} </h2>
<ul aria-labelledby="list-summary" class="stack-large">
<li v-for="item in ToDoItems" :key="item.id">
<to-do-item
:label="item.label"
:done="item.done"
:id="item.id"
@checkbox-changed="updateDoneStatus(item.id)"
@item-deleted="deleteToDo(item.id)"
@item-edited="editToDo(item.id, $event)"
>
</to-do-item>
</li>
</ul>
</div>
</template>
<script>
import ToDoItem from "./components/ToDoItem.vue";
import ToDoForm from "./components/ToDoForm.vue";
import uniqueId from "lodash.uniqueid";
export default {
name: "app",
components: {
ToDoItem,
ToDoForm,
},
data() {
return {
ToDoItems: [],
};
},
methods: {
updateDoneStatus(toDoId) {
const toDoToUpdate = this.ToDoItems.find((item) => item.id === toDoId);
toDoToUpdate.done = !toDoToUpdate.done;
console.dir(toDoToUpdate.done)
},
};
</script>
Upvotes: 0
Views: 55
Reputation: 10826
I'm not an expert in vue, but I believe that the this.done
being assigned to isDone:
is only done once in data()
, and it wouldn't be done if the props change (the value of isDone
in data()
won't change when the prop done
changes). While in computed, isDone
will watch the done
prop value, and if that prop value changes, the computed will be notified and thus changes the isDone
data.
Upvotes: 1