Home > other >  How to delay v-model sync for a checkbox?
How to delay v-model sync for a checkbox?

Time:09-08

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.

  • Related