前言
本文参考vue3
Vue 提供了两个内置组件,可以帮助我们制作基于状态变化的过渡和动画
-
<Transition >
会在一个元素或组件进入和离开 DOM 时应用动画。 -
<TransitionGroup>
会在一个 v-for 列表中的元素或组件被插入,移动,或移除时应用动画。
说明
<TransitionGroup>
是一个内置组件,用于对 v-for 列表中的元素或组件的插入、移除和顺序改变添加动画效果。
进入 / 离开动画
<template>
<button @click="add">新增</button>
<TransitionGroup name="list" tag="ul">
<li v-for="item in items" :key="item">
{{ item }}
</li>
</TransitionGroup>
</template>
<script setup>
import { reactive, ref } from "vue";
const items = reactive([])
const add = () => items.push(Math.random())
</script>
<style scoped>
.list-enter-active,
.list-leave-active {
transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
transform: translateX(30px);
}
</style>
移动动画
优化进入 / 离开动画效果
<template>
<button @click="add">新增</button>
<TransitionGroup name="list" tag="ul">
<li v-for="item in items" :key="item">
{{ item }}
</li>
</TransitionGroup>
</template>
<script setup>
import { reactive, ref } from "vue";
const items = reactive([])
const add = () => items.push(Math.random())
</script>
<style scoped>
.list-move, /* 对移动中的元素应用的过渡 */
.list-enter-active,
.list-leave-active {
transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
transform: translateX(30px);
}
/* 确保将离开的元素从布局流中删除
以便能够正确地计算移动的动画。 */
.list-leave-active {
position: absolute;
}
</style>
渐进延迟列表动画
<script>
import gsap from "gsap";
const list = [
{ msg: "Bruce Lee" },
{ msg: "Jackie Chan" },
{ msg: "Chuck Norris" },
{ msg: "Jet Li" },
{ msg: "Kung Fury" },
];
export default {
data() {
return {
query: "",
};
},
computed: {
computedList() {
return list.filter((item) => item.msg.toLowerCase().includes(this.query));
},
},
methods: {
onBeforeEnter(el) {
el.style.opacity = 0;
el.style.height = 0;
},
onEnter(el, done) {
gsap.to(el, {
opacity: 1,
height: "1.6em",
delay: el.dataset.index * 0.15,
onComplete: done,
});
},
onLeave(el, done) {
gsap.to(el, {
opacity: 0,
height: 0,
delay: el.dataset.index * 0.15,
onComplete: done,
});
},
},
};
</script>
<template>
<input v-model="query" />
<TransitionGroup
tag="ul"
:css="false"
@before-enter="onBeforeEnter"
@enter="onEnter"
@leave="onLeave"
>
<li
v-for="(item, index) in computedList"
:key="item.msg"
:data-index="index"
>
{{ item.msg }}
</li>
</TransitionGroup>
</template>
和 <Transition>
的区别
<TransitionGroup>
支持和 <Transition>
基本相同的 props、CSS 过渡 class 和 JavaScript 钩子监听器,但有以下几点区别:
默认情况下,它不会渲染一个容器元素。但你可以通过传入 tag prop 来指定一个元素作为容器元素来渲染。
过渡模式在这里不可用,因为我们不再是在互斥的元素之间进行切换。
列表中的每个元素都必须有一个独一无二的 key attribute。
CSS 过渡 class 会被应用在列表内的元素上,而不是容器元素上。
当在
DOM
内模板中使用时,组件名需要写为<transition-group>
。