steve
steve

Reputation: 473

Animate adding/deleting items from todo list using transition

I have a todo list that is based on the example provided in the official vuejs documentation.

Example: https://jsfiddle.net/87Lfbzng/

<ul class="todo-list">
  <li v-for="todo in filteredTodos" class="todo" :key="todo.id" :class="{ completed: todo.completed, editing: todo == editedTodo }">
    <div class="view">
      <input class="toggle" type="checkbox" v-model="todo.completed">
      <label @dblclick="editTodo(todo)">{{ todo.title }}</label>
      <button class="destroy" @click="removeTodo(todo)"></button>
    </div>
    <input class="edit" type="text" v-model="todo.title" v-todo-focus="todo == editedTodo" @blur="doneEdit(todo)" @keyup.enter="doneEdit(todo)" @keyup.esc="cancelEdit(todo)">
  </li>
</ul>

The issue with this is that the items are removed/added instantly, with no animation. If I implement the transition tags as per the official documentation take effect. VueJS transitions

I've tried putting the transition tags inside the ul and that didn't work either.

My current attempt: https://jsfiddle.net/87Lfbzng/

CSS

.fade-enter-active,
.fade-leave-active {
  transition: opacity .5s;
}

.fade-enter,
.fade-leave-to
/* .fade-leave-active below version 2.1.8 */

  {
  opacity: 0;
}

Markup

<transition name="fade">
  <ul class="todo-list">
    <li v-for="todo in filteredTodos" class="todo" :key="todo.id" :class="{ completed: todo.completed, editing: todo == editedTodo }">
      <div class="view">
        <input class="toggle" type="checkbox" v-model="todo.completed">
        <label @dblclick="editTodo(todo)">{{ todo.title }}</label>
        <button class="destroy" @click="removeTodo(todo)"></button>
      </div>
      <input class="edit" type="text" v-model="todo.title" v-todo-focus="todo == editedTodo" @blur="doneEdit(todo)" @keyup.enter="doneEdit(todo)" @keyup.esc="cancelEdit(todo)">
    </li>

  </ul>
</transition>

Upvotes: 1

Views: 1011

Answers (3)

Kevin Lynch
Kevin Lynch

Reputation: 24713

You need to replace the ul tag with a transition tag. You then add the tag attribute to the transition tag with the value of ul.

<transition-group name="fade" tag="ul" class="todo-list">

https://jsfiddle.net/ducwpeam/

The official documentation covers this, using ul as an example: VueJs Documentation: List Moves

Upvotes: 2

Abdelillah Aissani
Abdelillah Aissani

Reputation: 3108

You are wrapping your ul only inside that transition... this will do nothing .. because your ul is static :

Vue provides a transition wrapper component, allowing you to add entering/leaving transitions for any element or component in the following contexts:

  • Conditional rendering (using v-if)

  • Conditional display (using v-show)

  • Dynamic components

  • Component root nodes

Instead you need to wrap your li elements inside a transition tag and this time it will be a transition-group because you have more than two elements :

<ul>
 <transition-group name="fade">
  <li></li>
  <li></li> 
   ...
 </transition-group>
</ul>

jsfiddle

Upvotes: 0

Aimal Khan
Aimal Khan

Reputation: 449

you can do this with plain css

.view {
   animation: fade-anim 0.4s ease
}
@keyframes fade-anim {
0% {
    opacity: 0;
}
100% {
    opacity: 1;
}

}

Upvotes: 0

Related Questions