Vue 3 is the up and coming version of Vue front end framework.
It builds on the popularity and ease of use of Vue 2.
In this article, we’ll look at creating list transitions.
List Move Transitions
We can add list move transitions.
For instance, we can use the transition-group component to display some effect when we the items change position:
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
<style>
.list-move {
transition: transform 0.8s ease;
}
</style>
</head>
<body>
<div id="app">
<button @click="shuffle">shuffle</button>
<transition-group name="list" tag="div">
<p v-for="item in items" :key="item">
{{ item }}
</p>
</transition-group>
</div>
<script>
const app = Vue.createApp({
data() {
return {
items: Array(10)
.fill()
.map(() => Math.random()),
};
},
methods: {
shuffle() {
this.items = _.shuffle(this.items);
}
}
});
app.mount("#app");
</script>
</body>
</html>
We added the list-move class with our transition effect to display it when the list is shuffled.
The list is shuffled with the Lodash shuffle method.
Staggering List Transitions
We can stagger transitions in a list.
To do that, we use the Greensock library to help us.
We can write;
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/gsap.min.js"></script>
</head>
<body>
<div id="app">
<input v-model="query" />
<transition-group
name="fade"
tag="div"
:css="false"
@before-enter="beforeEnter"
@enter="enter"
@leave="leave"
>
<p
v-for="(item, index) in computedList"
:key="item.name"
:data-index="index"
>
{{ item.name }}
</p>
</transition-group>
</div>
<script>
const app = Vue.createApp({
data() {
return {
query: "",
list: [
{ name: "james" },
{ name: "mary" },
{ name: "alex" },
{ name: "bob" },
{ name: "jane" }
]
};
},
computed: {
computedList() {
return this.list.filter(item => {
return item.name.toLowerCase().includes(this.query.toLowerCase());
});
}
},
methods: {
beforeEnter(el) {
el.style.opacity = 0;
el.style.height = 0;
},
enter(el, done) {
gsap.to(el, {
opacity: 1,
height: "1.3em",
delay: el.dataset.index * 0.55,
onComplete: done
});
},
leave(el, done) {
gsap.to(el, {
opacity: 0,
height: 0,
delay: el.dataset.index * 0.45,
onComplete: done
});
}
}
});
app.mount("#app");
</script>
</body>
</html>
We included the Greensock library with our app.
In the methods property, we have a few methods.
The beforeEnter method sets the container’s opacity and height to 0.
The enter method has our enter animation effect.
We change the opacity to 1 to make opaque.
height is th height of the container.
delay is the delay of the animation.
onComplete is a function we call to notify Vue that the animation is done.
We do the same thing with the leave transition.
When computedList returns a new value, the animation effects will be applied.
Therefore, when we type in something into the input box, we’ll see the effects applied.
Reusable Transitions
We can make our transitions reusable by moving it into our own component.
For instance, we can write:
<!DOCTYPE html>
<html lang="en">
<head>
<title>App</title>
<script src="https://unpkg.com/vue@next"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/gsap.min.js"></script>
</head>
<body>
<div id="app">
<input v-model="query" />
<list-transition>
<p
v-for="(item, index) in computedList"
:key="item.name"
:data-index="index"
>
{{ item.name }}
</p>
</list-transition>
</div>
<script>
const app = Vue.createApp({
data() {
return {
query: "",
list: [
{ name: "james" },
{ name: "mary" },
{ name: "alex" },
{ name: "bob" },
{ name: "jane" }
]
};
},
computed: {
computedList() {
return this.list.filter(item => {
return item.name.toLowerCase().includes(this.query.toLowerCase());
});
}
}
});
app.component("list-transition", {
template: `
<transition-group
name="fade"
tag="div"
:css="false"
@before-enter="beforeEnter"
@enter="enter"
@leave="leave"
>
<slot></slot>
</transition-group>
`,
methods: {
beforeEnter(el) {
el.style.opacity = 0;
el.style.height = 0;
},
enter(el, done) {
gsap.to(el, {
opacity: 1,
height: "1.3em",
delay: el.dataset.index * 0.55,
onComplete: done
});
},
leave(el, done) {
gsap.to(el, {
opacity: 0,
height: 0,
delay: el.dataset.index * 0.45,
onComplete: done
});
}
}
});
app.mount("#app");
</script>
</body>
</html>
to move our transition component and hooks to its own component.
We just create a component and add a slot in between the transition-group tags to add the slot for our content.
Now we can use the list-transition component everywhere.
Conclusion
We can add our list transitions effects with the transition-group component.
It takes various directives to let us add hooks to create JavaScript animations.