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 v-if="!isEditing">
<div >
<input
type="checkbox"
:id="id"
:checked="isDone"
@change="$emit('checkbox-changed')"
/>
<label :for="id" >{{ label }}</label>
</div>
<div >
<button
type="button"
ref="editButton"
@click="toggleToItemEditForm"
>
Edit <span >{{ label }}</span>
</button>
<button type="button" @click="deleteToDo">
Delete <span >{{ 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" >
<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>
CodePudding user response:
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.