vue3学习记录-transition

时间:2024-10-19 08:13:01

vue3学习记录-transition

  • 1.基础用法
  • 2.自定义css名
    • 2.1用法
    • 2.2 和 Animate.css一起使用
  • 3. transition的生命周期钩子
  • 4.appear属性
  • 5.使用 Key Attribute 过渡

1.基础用法

是一个内置组件,这意味着它在任意别的组件中都可以被使用,无需注册。它可以将进入和离开动画应用到通过默认插槽传递给它的元素或组件上。进入或离开可以由以下的条件之一触发:

由 v-if 所触发的切换
由 v-show 所触发的切换
由特殊元素 切换的动态组件
改变特殊的 key 属性

基本上就是用在“改变”组件中,Vue 会自动检测元素的插入、删除或更新,触发相应的过渡效果。

<script setup>
import { ref } from 'vue';
const flag = ref(true);
</script>
<template>
  <el-button @click="flag = !flag">switch</el-button>
  <transition name="fade">
    <div class="box" v-if="flag"></div>
  </transition>

</template>
<style lang="scss" scoped>
.box {
  width: 200px;
  height: 200px;
  background-color: aqua;
}
.fade-enter-from{
  width: 0;
  height: 0;
}
.fade-enter-active{
  transition: all 1s ease;
}
.fade-enter-to{
  width: 200px;
  height: 200px;
}
.fade-leave-from{
  width: 200px;
  height: 200px;
}
.fade-leave-active{
  transition: all 1s ease;
}
.fade-leave-to{
  width: 0;
  height: 0;
}

</style>

用transition标签把div包裹,标签加上个name属性,这样vue就会提供了 6 个 CSS 类名(如 name属性-enter-from, name属性-enter-active, name属性-enter-to 等),方便定义不同阶段的样式。如果不写name属性的话,vue默认提供的css类名是(如 v-enter-from, v-enter-active, v-enter-to 等)

2.自定义css名

2.1用法

你也可以向 传递以下的 props 来指定自定义的过渡 class:

enter-from-class
enter-active-class
enter-to-class
leave-from-class
leave-active-class
leave-to-class

  <transition 
  name="fade" 
  enter-from-class="v-e-from" 
  enter-active-class="v-e-active" 
  enter-to-class="v-e-to"
  leave-from-class="v-l-from" 
  leave-active-class="v-l-active" 
  leave-to-class="v-l-to">
    <div class="box" v-if="flag"></div>
  </transition>
  .v-e-from {
  width: 0;
  height: 0;
}

.v-e-active {
  transition: all 1s ease;
}

.v-e-to {
  width: 200px;
  height: 200px;
}

.v-l-from {
  width: 200px;
  height: 200px;
}

.v-l-active {
  transition: all 1s ease;
}

.v-l-to {
  width: 0;
  height: 0;
}

可以达到一样的效果

2.2 和 Animate.css一起使用

下载依赖

npm install animate.css --save

//引入
import 'animate.css';
//使用
<transition 
  name="fade" 
  enter-active-class="animate__animated animate__bounce" 
>
    <div class="box" v-if="flag"></div>
  </transition>

不用再自己写css样式也能达到动画效果了。
你可以通过向 组件传入 duration prop 来显式指定过渡的持续时间 (以毫秒为单位)

<Transition :duration="550">...</Transition>

如果有必要的话,你也可以用对象的形式传入,分开指定进入和离开所需的时间:

<Transition :duration="{ enter: 500, leave: 800 }">...</Transition>

3. transition的生命周期钩子

<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) {}

举个例子,使用这些钩子搭配gsap来创建一个更复杂的动画效果,一个带有"弹跳"效果的淡入淡出动画。

<template>
  <button @click="show = !show">Toggle</button>
  <transition
    @before-enter="beforeEnter"
    @enter="enter"
    @after-enter="afterEnter"
    @before-leave="beforeLeave"
    @leave="leave"
    @after-leave="afterLeave"
  >
    <div v-if="show" class="box">Hello Vue 3!</div>
  </transition>
</template>

<script setup>
import { ref } from 'vue';
import gsap from 'gsap';

const show = ref(false);

const beforeEnter = (el) => {
  el.style.opacity = 0;
  el.style.transform = 'scale(0.8)';
};

const enter = (el, done) => {
  gsap.to(el, {
    duration: 0.5,
    opacity: 1,
    scale: 1,
    ease: 'elastic.out(1, 0.5)',
    onComplete: done
  });
};

const afterEnter = (el) => {
  console.log('Enter animation completed');
};

const beforeLeave = (el) => {
  el.style.opacity = 1;
  el.style.transform = 'scale(1)';
};

const leave = (el, done) => {
  gsap.to(el, {
    duration: 0.5,
    opacity: 0,
    scale: 0.8,
    ease: 'back.in(1.5)',
    onComplete: done
  });
};

const afterLeave = (el) => {
  console.log('Leave animation completed');
};
</script>

<style scoped>
.box {
  width: 200px;
  height: 100px;
  background-color: #42b883;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  font-size: 18px;
  border-radius: 8px;
}
</style>

可以使用钩子来实现动画,当然也可以做些其他的事情。

4.appear属性

在某个节点初次渲染时应用一个过渡效果,即不用点击就可以自动渲染一个动画。

<template>
  <button @click="show = !show">Toggle</button>
  <Transition appear>
    <div v-if="show" class="box">Hello Vue 3!</div>
  </Transition>
</template>

<script setup>
import { ref } from 'vue';
const show = ref(true);
</script>

<style scoped>
.box {
  width: 200px;
  height: 100px;
  background-color: #42b883;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  font-size: 18px;
  border-radius: 8px;
}

.v-enter-active,
.v-leave-active {
  transition: all 1s ease;
}

.v-enter-from,
.v-leave-to {
  opacity: 0;
  transform: scale(0.8);
}

.v-enter-to,
.v-leave-from {
  opacity: 1;
  transform: scale(1);
}

.v-enter-active1 {
  transition: all 5s ease;
  
}
.v-enter-to1 {
  opacity: 1;
  transform: scale(1);
  background-color: lightcoral;
}
.v-enter-from1{
  opacity: 1;
  transform: scale(0.5);
  background-color: lightgreen;
}
</style>

如果只加appear属性,效果默认的是v-enter-from,v-enter-active,v-enter-to;注意这里的v-if绑定的布尔值要为true;

<template>
  <button @click="show = !show">Toggle</button>
  <Transition appear appear-from-class="v-enter-from1" appear-active-class="v-enter-active1" appear-to-class="v-enter-to1">
    <div v-if="show" class="box">Hello Vue 3!</div>
  </Transition>
</template>

<script setup>
import { ref } from 'vue';
const show = ref(true);
</script>

<style scoped>
.box {
  width: 200px;
  height: 100px;
  background-color: #42b883;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  font-size: 18px;
  border-radius: 8px;
}
.v-enter-active1 {
  transition: all 5s ease;
  
}
.v-enter-to1 {
  opacity: 1;
  transform: scale(1);
  background-color: lightcoral;
}
.v-enter-from1{
  opacity: 1;
  transform: scale(0.5);
  background-color: lightgreen;
}
</style>

还可以指定appear-from-class, appear-active-class,appear-to-class属性名

5.使用 Key Attribute 过渡

有时为了触发过渡,你需要强制重新渲染 DOM 元素。

以计数器组件为例:

<script setup>
import { ref } from 'vue';
const count = ref(0);

setInterval(() => count.value++, 1000);
</script>

<template>
  <Transition>
    <span :key="count">{{ count }}</span>
  </Transition>
</template>

如果不使用 key attribute,则只有文本节点会被更新,因此不会发生过渡。但是,有了 key 属性,Vue 就知道在 count 改变时创建一个新的 span 元素,因此 Transition 组件有两个不同的元素在它们之间进行过渡。