Directorio de artículos
En Vue3, muchos componentes integrados pueden ayudarnos a desarrollar aplicaciones de manera más conveniente. En este blog, presentaremos
transition
&
transition-group
componentes, y su uso.
1. componente de transición
<transition>
Los componentes se utilizan para agregar efectos de transición cuando se insertan o eliminan elementos. Por ejemplo, cuando agregamos o eliminamos elementos de una lista, podemos usar <transition>
componentes para animar estas acciones. El uso específico es el siguiente:
1.1 Uso básico
<template>
<div>
<button @click="show = !show">显示/隐藏</button>
<transition>
<div v-if="show">Hello, World!</div>
</transition>
</div>
</template>
<script setup lang="ts">
import {
ref } from 'vue';
const show = ref(false)
</script>
<style scoped>
.v-enter-active,
.v-leave-active {
transition: opacity 2s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
</style>
En el código anterior, usamos <transition>
componentes para <div>
envolver elementos. Cuando la condición show
estrue
, <div>
el elemento se insertará en el DOM y se mostrará una animación de transición. Cuando la condición show
esfalse
, <div>
el elemento se elimina del DOM.
1.2 Introducción a la clase de transición css
Cuando no tiene nombre, hay un total de 6 clases de CSS que se aplican a las transiciones de entrada y salida.
-
v-enter-from
: Introduzca el estado de inicio de la animación. Agregado antes de la inserción del elemento, eliminado en el siguiente cuadro después de que se completa la inserción del elemento. -
v-enter-active
: Introduzca el estado efectivo de animación. Se aplica a toda la fase de animación de entrada. Se agrega antes de que se inserte el elemento y se elimina después de que se completa la transición o la animación. Esta clase se puede utilizar para definir la duración, el retraso y el tipo de curva de velocidad de la animación entrante. -
v-enter-to
: Introduzca el estado final de la animación. Se agregó el siguiente cuadro después de completar la inserción del elemento (es decir, al mismo tiempo que se elimina v-enter-from) y se elimina después de que se completan las transiciones o animaciones. -
v-leave-from
: deja el estado de inicio de la animación. Se agrega inmediatamente cuando se activa la transición de salida, se elimina un cuadro después. -
v-leave-active
: deja el estado activo de la animación. Se aplica a toda la fase de animación de salida. Se agrega inmediatamente cuando se activa la transición de salida y se elimina una vez que se completa la transición o la animación. Esta clase se puede utilizar para definir la duración, el retraso y el tipo de curva de velocidad de la animación de salida. -
v-leave-to
: Deja el estado final de la animación. Se agregó el siguiente cuadro después de que se activa una animación de salida (es decir, al mismo tiempo que se elimina v-leave-from), y se elimina después de que se completa la transición o la animación.
1.3 Nombre el efecto de transición
Para una transición con un nombre, el nombre que se le aplicará 过渡 class
tendrá como v
prefijo su nombre. El siguiente es un ejemplo de nomenclatura de transición:
1.3.1 Uso básico
<template>
<div>
<button @click="show = !show">显示/隐藏</button>
<transition name="hide">
<div v-if="show">Hello, World!</div>
</transition>
</div>
</template>
<script setup lang="ts">
import {
ref } from 'vue';
const show = ref(false)
</script>
<style scoped>
.hide-enter-active,
.hide-leave-active {
transition: opacity 2s ease;
}
.hide-enter-from,
.hide-leave-to {
opacity: 0;
}
</style>
Nota: <Transition>
Por lo general, se 原生 CSS 过渡
usan juntos, como se ve en el ejemplo anterior. Esta propiedad es una abreviatura que nos permite definir todos los aspectos de una transición a la vez, incluidos , y , transition CSS
que deben animarse .属性
持续时间
速度曲线
1.4 Uso con animación personalizada (animación)
原生 CSS 动画
y CSS transition
se aplican básicamente de la misma manera, con la excepción de que en lugar de *-enter-from
eliminarse inmediatamente después de insertar el elemento, se animationend
elimina cuando se activa un evento.
Para la mayoría de ellos CSS 动画
, *-enter-active
simplemente *-leave-active class
declararlos bajo y . Aquí hay un ejemplo:
<template>
<div>
<button @click="show = !show">显示/隐藏</button>
<transition name="hide">
<div v-if="show">Hello, World!</div>
</transition>
</div>
</template>
<script setup lang="ts">
import {
ref } from 'vue';
const show = ref(false)
</script>
<style scoped>
.hide-enter-active {
animation: scsle-in 0.5s;
}
.hide-leave-active {
animation: scsle-in 0.5s reverse;
}
@keyframes scsle-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.25);
}
100% {
transform: scale(1);
}
}
</style>
1.5 Clase de transición personalizada
Puede <Transition>
pasar los siguientes accesorios para especificar una clase de transición personalizada:
- entrar desde la clase
- entrar-clase-activa
- entrar a clase
- salir de clase
- dejar-clase-activa
- salir a clase
Estas clases pasadas anularán los nombres de clase predeterminados de las fases correspondientes. Esta característica es muy útil cuando desea integrar otras bibliotecas de animación CSS de terceros bajo el mecanismo de animación de Vue, como Animate.css
:
<template>
<button @click="show = !show">Toggle</button>
<Transition
name="custom-classes"
enter-active-class="animate__animated animate__tada"
leave-active-class="animate__animated animate__bounceOutRight"
>
<p v-if="show">hello</p>
</Transition>
</template>
<script setup>
import {
ref } from 'vue'
const show = ref(true)
</script>
<style>
@import "https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css";
</style>
1.6 <Transition>
Ciclo de vida de los componentes
<Transition
@before-enter="onBeforeEnter"
@enter="onEnter"
@after-enter="onAfterEnter"
@enter-cancelled="onEnterCancelled"
@before-leave="onBeforeLeave"
@leave="onLeave"
@after-leave="onAfterLeave"
@leave-cancelled="onLeaveCancelled"
>
<!-- ... -->
</Transition>
// 在元素被插入到 DOM 之前被调用
// 用这个来设置元素的 "enter-from" 状态
function onBeforeEnter(el) {
}
// 在元素被插入到 DOM 之后的下一帧被调用
// 用这个来开始进入动画
function onEnter(el, done) {
// 调用回调函数 done 表示过渡结束
// 如果与 CSS 结合使用,则这个回调是可选参数
done()
}
// 当进入过渡完成时调用。
function onAfterEnter(el) {
}
function onEnterCancelled(el) {
}
// 在 leave 钩子之前调用
// 大多数时候,你应该只会用到 leave 钩子
function onBeforeLeave(el) {
}
// 在离开过渡开始时调用
// 用这个来开始离开动画
function onLeave(el, done) {
// 调用回调函数 done 表示过渡结束
// 如果与 CSS 结合使用,则这个回调是可选参数
done()
}
// 在离开过渡完成、
// 且元素已从 DOM 中移除时调用
function onAfterLeave(el) {
}
// 仅在 v-show 过渡中可用
function onLeaveCancelled(el) {
}
1.7 Escenarios comunes de transición
- Efectos de transición reutilizables
El efecto de transición en vue
Medium se puede empaquetar y reutilizar. Para crear una transición que se pueda reutilizar, necesitamos <Transition>
crear un componente contenedor para el componente y pasar el contenido de la ranura:
<!-- MyTransition.vue -->
<script>
// JavaScript 钩子逻辑...
</script>
<template>
<!-- 包装内置的 Transition 组件 -->
<Transition
name="my-transition"
@enter="onEnter"
@leave="onLeave">
<slot></slot> <!-- 向内传递插槽内容 -->
</Transition>
</template>
<style>
/*
必要的 CSS...
注意:避免在这里使用 <style scoped>
因为那不会应用到插槽内容上
*/
</style>
Ahora MyTransition
se puede importar y usar como un componente integrado:
<MyTransition>
<div v-if="show">Hello</div>
</MyTransition>
- Transición al aparecer
Si desea aplicar un efecto de transición cuando se procesa un nodo por primera vez, puede agregar appear prop
:
<Transition appear>
...
</Transition>
- transición entre elementos
Además de v-if / v-show
cambiar un elemento, también podemos v-if / v-else / v-else-if
cambiar entre varios componentes, solo asegúrese de que solo se represente un elemento a la vez:
<Transition>
<button v-if="docState === 'saved'">Edit</button>
<button v-else-if="docState === 'edited'">Save</button>
<button v-else-if="docState === 'editing'">Cancel</button>
</Transition>
- modo de transición
En el ejemplo anterior, los elementos de entrada y salida estaban animados al mismo tiempo, por lo que tuvimos que configurarlos position: absolute
para evitar problemas de diseño cuando ambos estaban presentes.
Sin embargo, en muchos casos esto puede no satisfacer las necesidades. Es posible que deseemos realizar la animación de salida primero y luego realizar la animación de entrada del elemento después de que se complete. Programar manualmente una animación de este tipo es muy complicado, pero podemos lograr este comportamiento <Transition>
pasando un :`mode prop
<Transition mode="out-in">
...
</Transition>
- transición entre componentes
<Transition>
También se puede utilizar para cambiar entre componentes dinámicos:
<Transition name="fade" mode="out-in">
<component :is="activeComponent"></component>
</Transition>
- transición dinámica
<Transition>
también puede props (比如 name)
ser dinámico! Esto nos permite aplicar dinámicamente diferentes tipos de transiciones en función de los cambios de estado:
<Transition :name="transitionName">
<!-- ... -->
</Transition>
La utilidad de esta función es que puede definir varios grupos por adelantado CSS 过渡或动画的 class
y luego alternar dinámicamente entre ellos.
2. componente del grupo de transición
<TransitionGroup>
Los soportes y <Transition>
son básicamente los mismos que props
, CSS 过渡 class
y JavaScript 钩子监听器
, pero con las siguientes diferencias:
-
De forma predeterminada, no representará un elemento contenedor. Pero puede
tag prop
especificar un elemento para que se represente como un elemento contenedor pasándolo. -
过渡模式
No disponible aquí porque ya no cambiamos entre elementos mutuamente excluyentes. -
Cada elemento de la lista debe tener un único
key attribute
. -
CSS
Las transicionesclass
se aplicarán a los elementos dentro de la lista, no a los elementos contenedores.
<transition-group>
Los componentes se utilizan para agregar efectos de transición cuando se insertan o eliminan varios elementos. Por ejemplo, cuando agregamos o eliminamos elementos en una lista, podemos usar <transition-group>
componentes para animar estas acciones. El uso específico es el siguiente:
2.1 Uso básico
<template>
<div>
<button @click="handleAddLi">显示/隐藏</button>
<transition-group tag="ul">
<li v-for="item in items" :key="item.id">{
{ item.text }}</li>
</transition-group>
</div>
</template>
<script setup lang="ts">
import {
reactive } from 'vue';
const items = reactive([
{
id: 1,
text: 'test1'
},
{
id: 2,
text: 'test2'
}
])
const handleAddLi = () => {
items.push({
id: items.length + 1,
text: 'test' + (items.length + 1)
})
}
</script>
<style scoped>
.v-enter-active,
.v-leave-active {
transition: opacity 2s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
</style>
En el código anterior, usamos <transition-group>
componentes para <ul>
envolver un elemento y usamos v-for
directivas para representar una lista.