Timo002
Timo002

Reputation: 3208

Vue adding items to list with animation

I've created a Vue application with socket.io that is showing real time information. Now I want some nice animation but I don't know how to do this with Vue.

Below you find the code that kind of represents this Vue application. Every 2 seconds some data is pushed that will be added to the HTML by Vue List Rendering.

In this example the current Date() is added to the list every 2 seconds. Also there is a function that maintains the list (maintainList) and takes care that the 5 latest entries are shown.

The wanted animation
Now I want some animation in this, ultimately what I want:
The "oldest" item (top one) slides out on top, all items below slide up one place and a new item slides in from the bottom. Or actually, all items slide up and those outside #app will not be shown.

var example1 = new Vue({
  el: '#app',
  data: {
    items: []
  },
  mounted() {
  	setInterval(this.add, 2000);
    
    setInterval(this.maintainList, 2000);
    
  },
  methods: {
  	add(){
    	this.items.push({
      	'message': new Date()
      });
    },
    
    maintainList(){
    	if(Object.keys(this.items).length >= 6){
      	this.items.shift();
      }
    }
  }
});

example1.add();
.box{
  padding: 15px;
  border: 1px solid black;
  margin-bottom: 15px;
  animation: fadein 1s;
}


@keyframes fadein {
  from {opacity: 0;}
  to   {opacity: 1;}
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>

<div id="app">
  <div v-for="item in items" class="box">
    {{ item.message }}
  </div>
</div>

Upvotes: 4

Views: 4903

Answers (1)

Mohd_PH
Mohd_PH

Reputation: 1677

Check out Transitions, to be specific List Entering/Leaving Transitions, and here is an example of use

var example1 = new Vue({
  el: '#app',
  data: {
    items: []
  },
  mounted() {
    //setInterval(this.add, 2000);
    
    //setInterval(this.maintainList, 2000);
    
  },
  methods: {
    add(){
        this.items.push({
        'message': new Date()
      });
      setTimeout(this.maintainList, 1000);
    },
    
    maintainList(){
        if(Object.keys(this.items).length >= 4){
        this.items.splice(0,1);
      }
    }
  }
});
.box{
  padding: 15px;
  border: 1px solid black;
  margin-bottom: 15px;
}

.fade-enter {
  opacity:0;
}

.fade-enter-active{
  animation: fadein 1s;
}

.fade-leave {
  opacity:1;
}

.fade-leave-active {
  animation: fadein 1s reverse;
}


@keyframes fadein {
  from {opacity: 0;}
  to   {opacity: 1;}
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>

<div id="app">
  <div>
    <button @click="add">Add new Item</button>
  </div>
  <transition-group name="fade" mode="out-in">
    <div   v-for="item in items" class="box" :key="item">
      {{ item.message }}
    </div>
  </transition-group>
  
</div>

Upvotes: 1

Related Questions