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.