the main effect to be accomplished here is that the current element moves to the left and disappears (the transparency gradually becomes 0 in the process), and the new element moves to the left to the position of the previous element (transparency changes from 0 to 1 in the process). The problem here is that the two div are not close to each other to complete the animation, but keep the distance all the time, making the whole effect too stiff.
the following is the full source code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue - (runoob.com)</title>
<style>
.d {
position: relative;
border: 1px solid red;
width: 30px;
height: 30px;
}
@keyframes show {
0% {
opacity: 0;
transform: translateX(30px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
@keyframes hide {
0% {
opacity: 1;
transform: translateX(0);
}
100% {
opacity: 0;
transform: translateX(-30px);
}
}
.show-enter-active {
animation: show 2s;
}
.show-leave-active {
animation: hide 1s;
}
.show-enter, .show-leave-to {
opacity: 0;
}
.wrap {
display: flex;
}
</style>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
{{ message }}
<div class="wrap">
<transition name="show">
<div class="d" v-for="item in list" :key="item.id" v-if="count === item.id">
{{ item.text }}
</div>
</transition>
</div>
<button @click="add">add</button>
</div>
<script>
new Vue({
el: "-sharpapp",
data () {
return {
message: "Hello Vue.js!",
count: 0,
list: [
{id: 0, text: "aaa"},
{id: 1, text: "bbb"},
{id: 2, text: "ccc"}
]
}
},
methods: {
add: function () {
if (this.count < this.list.length - 1) {
this.count += 1;
} else {
this.count = 0;
}
}
}
})
</script>
</body>
</html>