首页 > 其他分享 >vue:Transition

vue:Transition

时间:2024-11-08 21:15:13浏览次数:3  
标签:动画 vue Transition leave 过渡 enter active CSS

1. Transition

1. 基本用法

<Transition> 是Vue 提供的 “内置组件动画组件”,与一般的CSS过渡动画不同的是,它通过在特点时刻给元素或组件增加、移除类名来实现——在一个元素或组件进入和离开 DOM 时应用过渡动画。

下面是一个基本用法:注意:Transition只能包含一个直接根节点元素

<el-button @click="update">动画</el-button>
<Transition>
  <p v-if="isShow">'Hello, World!'</p>
</Transition>

/* 下面会解释这些 class 是做什么的 */
.v-enter-active,
.v-leave-active {
  transition: all 0.5s ease;
}
.v-enter-from,
.v-leave-to {
  opacity: 0;
  transform: translateX(-30px);
}

上面提到 过渡动画会在元素或组件进入和离开 DOM 时被应用,那么具体有哪些情况会触发呢:

        1.由 v-if 和 v-show,或v-if / v-else / v-else-if  所触发的切换

<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>

        2. 由特殊元素 <component> 切换的动态组件,就是常被<keep-alive>包裹的那个

<Transition name="fade" mode="out-in">
  <component :is="activeComponent"></component>
</Transition>

        3. 改变特殊的 key 属性,比如v-for中的key值

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

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

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

2. 基于 CSS 的过渡效果

当一个 <Transition> 组件中的元素被插入或移除时,Vue 会自动检测目标元素是否应用了 CSS 过渡或动画。如果是,则一些 CSS 过渡 class 会在适当的时机被添加和移除。

1. 过渡的class

一共有 6 个应用于进入与离开过渡效果的 CSS class,如下:

  1. v-enter-from进入动画的起始状态。在元素插入之前添加,插入完成后的下一帧移除。

  2. v-enter-active进入动画的生效状态应用于整个进入动画阶段。在元素插入之前添加,在过渡或动画完成之后移除。这个 class 可以被用来定义进入动画的持续时间、延迟与速度曲线类型。

  3. v-enter-to进入动画的结束状态。在 v-enter-from 被移除的同时添加,在过渡或动画完成之后移除。

  4. v-leave-from离开动画的起始状态。在离开动画被触发时立即添加,在一帧后被移除。

  5. v-leave-active离开动画的生效状态,应用于整个离开动画阶段。在离开动画被触发时立即添加,在过渡或动画完成之后移除。这个 class 可以被用来定义离开动画的持续时间、延迟与速度曲线类型。

  6. v-leave-to离开动画的结束状态。在 v-leave-from 被移除的同时添加,在过渡或动画完成之后移除。


2. 为过渡效果命名

通过name="prop"来给<Transition>的过渡效果命名,这样过渡的class名字将不会以v作前缀,而是prop,如下:

​
<Transition name="fade">
  ...
</Transition>

​
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

3. CSS的 animation

原生CSS 的 animation与 transition的应用方式基本相同。

<el-button @click="update">动画</el-button>
<Transition name="slide">
  <p v-if="isShow">'Hello, World!'</p>
</Transition>

.slide-enter-active {
  animation: slide-in 0.5s;
}
.slide-leave-active {
  animation: slide-in 0.5s reverse;
}

@keyframes slide-in {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.25);
  }
  100% {
    transform: scale(1);
  }
}


4. 自定义过渡 class

有时候,我们会集成第三方CSS动画库(比如 Animate.css,或 GSAP 库),如果想要将这些动画赋予<Transition>,就可以使用下面的props来覆盖相应阶段的默认 class 名。

<!-- 假设你已经在页面中引入了 Animate.css -->
<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>
...............................
enter-from-class
enter-active-class
enter-to-class
leave-from-class
leave-active-class
leave-to-class

5. 内嵌元素动画

尽管过渡 class 仅能应用在 <Transition> 的直接子元素上,我们还是可以使用深层级的 CSS 选择器,在深层级的元素上触发过渡效果。

<Transition name="nested">
  <div v-if="show" class="outer">
    <div class="inner">
      Hello
    </div>
  </div>
</Transition>
​
/* 应用于嵌套元素的规则 */
.nested-enter-active .inner,
.nested-leave-active .inner {
  transition: all 0.3s ease-in-out;
}
.nested-enter-from .inner,
.nested-leave-to .inner {
  transform: translateX(30px);
  opacity: 0;
}
/* ... 省略了其他必要的 CSS */

我们甚至可以在深层元素上添加一个过渡延迟,从而创建一个带渐进延迟的动画序列:

/* 延迟嵌套元素的进入以获得交错效果 */
.nested-enter-active .inner {
  transition-delay: 0.25s;
}

但需要注意的是,<Transition> 组件默认会通过监听过渡根元素上的第一个 transitionend 或者 animationend 事件来尝试自动判断过渡何时结束。而在嵌套的过渡中,期望的行为应该是等待所有内部元素的过渡完成。

  在这种情况下,你可以通过向 <Transition> 组件传入 duration prop 来显式指定过渡的持续时间 (以毫秒为单位)。总持续时间应该匹配延迟加上内部元素的过渡持续时间:

<Transition :duration="550">...</Transition>
<--如果有必要的话,你也可以用对象的形式传入,分开指定进入和离开所需的时间-->
<Transition :duration="{ enter: 500, leave: 800 }">...</Transition>

3 JavaScript 钩子

除了CSS动画,我们还可以通过监听 <Transition> 组件事件,来注册JS动画。这些钩子函数与CSS的各个阶段相对应:

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

这些钩子可以与 CSS 过渡或动画结合使用,也可以单独使用。但如果只设置了JS动画而没有CSS动画时,建议添加一个 :css="false" prop,显式地向 Vue 表明可以跳过对 CSS 过渡的自动探测,提高性能的同时,也可以防止 CSS 规则意外地干扰过渡效果:

<Transition
  ...
  :css="false"
>
  ...
</Transition>

4. 过渡选项补充

1. 初次出现时过渡

向Transition添加 appear prop,可以实现节点初次渲染时就应用过渡效果

<Transition appear>
  ...
</Transition>

2. 过渡模式

在之前的例子中,由于进入和离开的元素都是在同时开始动画的

多元素或组件同时存在时出现的可能会出现布局问题,虽然可以通过复杂的CSS的 设置来编排动画,避免这个问题,但却官方提供了更简单的方法,向Transition添加mode prop:

<Transition mode="out-in">
  ...
</Transition>


3.动态过渡

<Transition> 的 props (比如 name) 也可以是动态的!这让我们可以根据状态变化动态地应用不同类型的过渡:

<Transition :name="transitionName">
  <!-- ... -->
</Transition>

 5. 复用过渡效果

我们可以通过包装<Transition>组件,并结合插槽的方式来实现动画效果的组件封装 

vue 3插槽传送门:vue 插槽-CSDN博客          插槽 Slots | Vue.js (vuejs.org)

TransCom.vue组件:

<script setup>
const prop = defineProps({
  nameProp: {// 动态设置 Transition 的名字
    type: String,
    default: 'slide',
  },
  isShow: {// 父组件控制 Transition 的显示和隐藏
    type: Boolean,
    default: true,
  },
})

// JavaScript 钩子逻辑...
</script>
<!-- 包装内置的 Transition 组件 -->
<template>
  <div class="trans-container">
    <Transition :name="prop.nameProp">
      <slot v-if="prop.isShow"></slot>
    </Transition>
    <Transition :name="prop.nameProp">
      <div v-if="$slots.other && prop.isShow" class="trans-other">
        <slot name="other"></slot>
      </div>
    </Transition>
  </div>
</template>
<style>
/*
  注意:避免在这里使用 <style scoped>
  因为那不会应用到插槽内容上
*/

.trans-other {
  background-color: aqua;
}
.slide-enter-active,
.slide-leave-active {
  transition: all 0.5s ease;
}

.slide-enter-from,
.slide-leave-to {
  opacity: 0;
  transform: translateX(-30px);
}
</style>

现在 TransCom可以在导入后像内置组件那样使用了:

<template>
  <el-card class="container">
    <template #header>
      <el-button @click="update">切换</el-button>
    </template>
    <TransCom name="slide" :isShow="isShow">
      <template #default>
        <p>'Hello, World!'</p>
      </template>
      <template #other>
        <p>'Hello, World!'</p>
      </template>
    </TransCom>
  </el-card>
</template>
<script setup>
import TransCom from '@/views/components/TransCom.vue'
import { ref } from 'vue'

const isShow = ref(true)
const update = () => {
  isShow.value = !isShow.value
}
</script>

2.TransitionGroup

1. 和 <Transition> 的区别

TransitionGroup主要用于对 v-for 列表中的元素或组件的插入、移除和顺序改变添加动画效果,它支持和<Transition> 基本相同的prop、CSS......但也有以下几个区别

  • 默认情况下,它不会渲染一个容器元素。但你可以通过传入 tag prop 来指定一个元素作为容器元素来渲染。
  • 过渡模式在这里不可用,因为我们不再是在互斥的元素之间进行切换。
  • 列表中的每个元素都必须有一个独一无二的 key attribute。
  • CSS 过渡 class 会被应用在列表内的元素上,而不是容器元素上。

2. 进入 / 离开动画

<TransitionGroup name="list" tag="ul">
  <li v-for="item in items" :key="item">
    {{ item }}
  </li>
</TransitionGroup>

.list-enter-active,
.list-leave-active {
  transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}


3. 移动动画

上面的示例有一些明显的缺陷:当某一项被插入或移除时,它周围的元素会立即发生“跳跃”而不是平稳地移动。我们可以通过添加一些额外的 CSS 规则来解决这个问题:


/* 1. 声明过渡效果 */
.fade-move,/* 对移动中的元素应用的过渡 */
.fade-enter-active,
.fade-leave-active {
  transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);
}

/* 2. 声明进入和离开的状态 */
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: scaleY(0.01) translate(30px, 0);
}

/* 3. 确保离开的项目被移除出了布局流
      以便正确地计算移动时的动画效果。 */
.fade-leave-active {
  position: absolute;
}


3. Transition和Vue Router  

路由传送门:Vue路由:Vue router-CSDN博客           官方介绍 | Vue Router (vuejs.org)

1. 基本用法

要在路径组件上使用转场,并对导航进行动画处理,需要使用 <RouterView> 插槽

<router-view v-slot="{ Component }">
  <transition name="fade">
    <component :is="Component" />
  </transition>
</router-view>

2. 单个路由过渡

上面的用法会对所有的路由使用相同的过渡。如果你想让每个路由的组件有不同的过渡,你可以将元信息和动态的 name 结合在一起,放在<transition> 上:

const routes = [
  {
    path: '/custom-transition',
    component: PanelLeft,
    meta: { transition: 'slide-left' },
  },
  {
    path: '/other-transition',
    component: PanelRight,
    meta: { transition: 'slide-right' },
  },
]
<router-view v-slot="{ Component, route }">
  <!-- 使用任何自定义过渡和回退到 `fade` -->
  <transition :name="route.meta.transition || 'fade'">
    <component :is="Component" />
  </transition>
</router-view>

若有错误或描述不当的地方,烦请评论或私信指正,万分感谢

标签:动画,vue,Transition,leave,过渡,enter,active,CSS
From: https://blog.csdn.net/m0_61619549/article/details/143518217

相关文章

  • (开题报告)django+vue校园二手物品交易平台源码+论文
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景关于校园二手物品交易平台的研究,现有研究多侧重于传统交易模式或者单一技术的应用。专门针对django+vue技术构建校园二手物品交易平......
  • 基于SpringBoot+Vue的装饰工程管理系统设计与实现毕设(文档+源码)
            目录一、项目介绍二、开发环境三、功能介绍四、核心代码五、效果图六、源码获取:         大家好呀,我是一个混迹在java圈的码农。今天要和大家分享的是一款基于SpringBoot+Vue的装饰工程管理系统,项目源码请点击文章末尾联系我哦~目前有各类成......
  • 基于SpringBoot+Vue的卓越导师双选管理系统设计与实现毕设(文档+源码)
            目录一、项目介绍二、开发环境三、功能介绍四、核心代码五、效果图六、源码获取:         大家好呀,我是一个混迹在java圈的码农。今天要和大家分享的是一款基于SpringBoot+Vue的卓越导师双选管理系统,项目源码请点击文章末尾联系我哦~目前有各......
  • flask毕设springboot+vue的网上书店项目(论文+程序)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容选题背景随着互联网技术的迅猛发展,电子商务已成为现代社会中不可或缺的一部分。网上书店作为电子商务的一个重要分支,凭借其便捷性、高效性和广泛的......
  • JAVA毕业设计198—基于Java+Springboot+vue3的健身房管理系统(源代码+数据库)
    毕设所有选题:https://blog.csdn.net/2303_76227485/article/details/131104075基于Java+Springboot+vue3的健身房管理系统(源代码+数据库)198一、系统介绍本项目前后端分离(可以改为ssm版本),分为用户、管理员两种角色1、用户:注册、登录、公告、论坛交流、健身课程购买......
  • Java+SpringBoot+Vue 学院个人信息管理系统
    学生个人信息管理一:基本介绍开发环境功能模块图系统功能部分数据库表设计用例分析二:部分系统页面展示登录页面首页管理端首页个人信息管理教师信息管理学生作业管理学习课程信息管理课程分类管理班级管理学生信息管理源码一:基本介绍开发环境·开发语言:Java·......
  • Vue3+antd实现分页功能
    vue中代码(在对应的地方添加)<a-paginationv-model:current="current":total="total"v-model:page-size="pageSize":showSizeChanger="true"......
  • vue页签
    效果:快来学习:Vue3CompositionAPI和scriptsetup语法CompositionAPI:Vue3引入的CompositionAPI相比Vue2的OptionsAPI提供了更灵活的代码组织方式。使用setup函数,可以将组件的所有功能和逻辑集中在一起,方便复用。scriptsetup语法:Vue3的<scriptsetu......
  • vue 表格头部创建
    <template> <viewclass="content"> <divclass="table"> <divclass="headflexCenterBox"> <divclass="line"v-for="(item,index)inparam":key="index"> ......
  • vue,for循环为什么不提倡放主键id
    在Vue.js中,v-for循环用于渲染列表时,推荐为每个列表项提供一个key属性,以帮助Vue更高效地更新和复用DOM元素。但是,使用主键id作为key有时并不推荐,原因如下:1.id不一定稳定主键id通常是在数据库中生成的唯一标识符,虽然在数据库中它是唯一的,但在前端应用中,尤其是在......