In a Vue app, I am rendering a list of tasks. Each task has a checkbox to mark it as Completed. I also have the option to show/hide completed tasks. When "showcompletedtasks" is false, if I mark an open task as completed, the task dissapears from the list (as intended) but it dissapears instantly, without the user even seing the checkbox check-animation.
I can put a delay on the database update, but it will still dissapear instantly from the DOM because the checkbox is v-modeled to local data (Vuex).
How can I delay the v-model update process? (So that the user sees the task checkbox actually being checked before dissapearing)? I have seen solutions that require using external libraries, but is there a simple solution to do this? Something like v-model.delay?
<template>
<!--begin::Item-->
<button @click="$store.state.showcompletedtasks = !$store.state.showcompletedtasks">
Show completed
</button>
<div
v-for="task in filteredTaskList"
:key="task.taskid"
>
<!--begin::Checkbox-->
<div >
<input
type="checkbox"
v-model="task.completed"
@click="handleProfileTaskCheckBox(task)"
>
</div>
<!--end::Checkbox-->
<!--begin::Description-->
<div >
<span
href="#"
>{{ task.text }}</span>
</div>
<!--end::Description-->
</div>
<!--end:Item-->
</template>
<script>
export default {
methods: {
handleProfileTaskCheckBox(task) {
//here the task Completed status will be updated in Firebase/Firestore
},
},
computed: {
filteredTaskList() {
if (this.$store.state.showcompletedtasks) {
//return all tasks, completed & uncompleted
const originalTaskList = this.$store.state.currentProfileTasks;
return originalTaskList;
} else if (!this.$store.state.showcompletedtasks) {
//return only uncompleted tasks
const originalTaskList = this.$store.state.currentProfileTasks;
const results = originalTaskList.filter((obj) => {
return obj.completed === false;
});
return results;
}
},
},
};
</script>
<style>
</style>
CodePudding user response:
There is no such thing as the delay
that you expect.
As you might know, the concept of VueJS and other similar libs is:
view = f(state)
So, given the input data as filteredTaskList
, if you mark the task as completed
, it will be removed from the filtered list and the UI must be invalidated and rerendered.
However, what you are expecting is achievable by animation
libraries/capabilities.
They call it exit animation
/ exit transition
or a similar name (not sure what is the correct name/term).
Fortunately, there is a way built-in in VueJS:
vue2: https://v2.vuejs.org/v2/guide/transitions.html#list-complete-demo
vue3: https://vuejs.org/guide/built-ins/transition.html#javascript-hooks
In Vue 2 example, if you click the remove button, you will see the item will be moved down before being completely removed from the list. You can replace that transition with your our transition to help the completed task stands out before removing it.
Similar to Vue 3 example, click the toggle button make the ball move before completely shutting down. Replace that with your own animation.
Hope it will help.