Vue内置组件Transition用法介绍

Vue 提供了两个内置组件,可以帮助你制作基于状态变化的过渡和动画:

  • <Transition> 会在一个元素或组件进入和离开 DOM 时应用动画。本章节会介绍如何使用它。

  • <TransitionGroup> 会在一个 v-for 列表中的元素或组件被插入,移动,或移除时应用动画。

除了这两个组件,我们也可以通过其他技术手段来应用动画,比如切换 CSS class 或用状态绑定样式来驱动动画。

 

<Transition> 组件​

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

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

以下是最基本用法的示例:

<button @click="show = !show">Toggle</button>
<Transition><p v-if="show">hello</p>
</Transition>
/* 下面我们会解释这些 class 是做什么的 */
.v-enter-active,
.v-leave-active {transition: opacity 0.5s ease;
}.v-enter-from,
.v-leave-to {opacity: 0;
}

TIP

<Transition> 仅支持单个元素或组件作为其插槽内容。如果内容是一个组件,这个组件必须仅有一个根元素。

当一个 <Transition> 组件中的元素被插入或移除时,会发生下面这些事情:

  1. Vue 会自动检测目标元素是否应用了 CSS 过渡或动画。如果是,则一些 CSS 过渡 class 会在适当的时机被添加和移除。

  2. 如果有作为监听器的 JavaScript 钩子,这些钩子函数会在适当时机被调用。

  3. 如果没有探测到 CSS 过渡或动画、也没有提供 JavaScript 钩子,那么 DOM 的插入、删除操作将在浏览器的下一个动画帧后执行。

基于 CSS 的过渡效果​

CSS 过渡 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 被移除的同时),在过渡或动画完成之后移除。

v-enter-active 和 v-leave-active 给我们提供了为进入和离开动画指定不同速度曲线的能力,我们将在下面的小节中看到一个示例。

为过渡效果命名​

我们可以给 <Transition> 组件传一个 name prop 来声明一个过渡效果名:

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

对于一个有名字的过渡效果,对它起作用的过渡 class 会以其名字而不是 v 作为前缀。比如,上方例子中被应用的 class 将会是 fade-enter-active 而不是 v-enter-active。这个“fade”过渡的 class 应该是这样:

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

CSS 的 transition​

<Transition> 一般都会搭配原生 CSS 过渡一起使用,正如你在上面的例子中所看到的那样。这个 transition CSS 属性是一个简写形式,使我们可以一次定义一个过渡的各个方面,包括需要执行动画的属性、持续时间和速度曲线

下面是一个更高级的例子,它使用了不同的持续时间和速度曲线来过渡多个属性:

<Transition name="slide-fade"><p v-if="show">hello</p>
</Transition>
/*进入和离开动画可以使用不同持续时间和速度曲线。
*/
.slide-fade-enter-active {transition: all 0.3s ease-out;
}.slide-fade-leave-active {transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
}.slide-fade-enter-from,
.slide-fade-leave-to {transform: translateX(20px);opacity: 0;
}

CSS 的 animation​

原生 CSS 动画和 CSS transition 的应用方式基本上是相同的,只有一点不同,那就是 *-enter-from 不是在元素插入后立即移除,而是在一个 animationend 事件触发时被移除。

对于大多数的 CSS 动画,我们可以简单地在 *-enter-active 和 *-leave-active class 下声明它们。下面是一个示例:

<Transition name="bounce"><p v-if="show" style="text-align: center;">Hello here is some bouncy text!</p>
</Transition>
.bounce-enter-active {animation: bounce-in 0.5s;
}
.bounce-leave-active {animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {0% {transform: scale(0);}50% {transform: scale(1.25);}100% {transform: scale(1);}
}

自定义过渡 class​

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

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

你传入的这些 class 会覆盖相应阶段的默认 class 名。这个功能在你想要在 Vue 的动画机制下集成其他的第三方 CSS 动画库时非常有用,比如 Animate.css

<!-- 假设你已经在页面中引入了 Animate.css -->
<Transitionname="custom-classes"enter-active-class="animate__animated animate__tada"leave-active-class="animate__animated animate__bounceOutRight"
><p v-if="show">hello</p>
</Transition>

同时使用 transition 和 animation​

Vue 需要附加事件监听器,以便知道过渡何时结束。可以是 transitionend 或 animationend,这取决于你所应用的 CSS 规则。如果你仅仅使用二者的其中之一,Vue 可以自动探测到正确的类型。

然而在某些场景中,你或许想要在同一个元素上同时使用它们两个。举例来说,Vue 触发了一个 CSS 动画,同时鼠标悬停触发另一个 CSS 过渡。此时你需要显式地传入 type prop 来声明,告诉 Vue 需要关心哪种类型,传入的值是 animation 或 transition

<Transition type="animation">...</Transition>

深层级过渡与显式过渡时长​

尽管过渡 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 来显式指定过渡的持续时间 (以毫秒为单位)。总持续时间应该匹配延迟加上内部元素的过渡持续时间:

template

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

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

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

性能考量​

你可能注意到我们上面例子中展示的动画所用到的 CSS 属性大多是 transform 和 opacity 之类的。用这些属性制作动画非常高效,因为:

  1. 他们在动画过程中不会影响到 DOM 结构,因此不会每一帧都触发昂贵的 CSS 布局重新计算。

  2. 大多数的现代浏览器都可以在执行 transform 动画时利用 GPU 进行硬件加速。

相比之下,像 height 或者 margin 这样的属性会触发 CSS 布局变动,因此执行它们的动画效果更昂贵,需要谨慎使用。我们可以在 CSS-Triggers 这类的网站查询哪些属性会在执行动画时触发 CSS 布局变动。

JavaScript 钩子​

你可以通过监听 <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) {}

这些钩子可以与 CSS 过渡或动画结合使用,也可以单独使用。

在使用仅由 JavaScript 执行的动画时,最好是添加一个 :css="false" prop。这显式地向 Vue 表明可以跳过对 CSS 过渡的自动探测。除了性能稍好一些之外,还可以防止 CSS 规则意外地干扰过渡效果:

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

在有了 :css="false" 后,我们就自己全权负责控制什么时候过渡结束了。这种情况下对于 @enter 和 @leave 钩子来说,回调函数 done 就是必须的。否则,钩子将被同步调用,过渡将立即完成。

可复用过渡效果​

得益于 Vue 的组件系统,过渡效果是可以被封装复用的。要创建一个可被复用的过渡,我们需要为 <Transition> 组件创建一个包装组件,并向内传入插槽内容:

<!-- MyTransition.vue -->
<script>
// JavaScript 钩子逻辑...
</script><template><!-- 包装内置的 Transition 组件 --><Transitionname="my-transition"@enter="onEnter"@leave="onLeave"><slot></slot> <!-- 向内传递插槽内容 --></Transition>
</template><style>
/*必要的 CSS...注意:避免在这里使用 <style scoped>因为那不会应用到插槽内容上
*/
</style>

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

<MyTransition><div v-if="show">Hello</div>
</MyTransition>

出现时过渡​

如果你想在某个节点初次渲染时应用一个过渡效果,你可以添加 appear prop:

template

<Transition appear>...
</Transition>

元素间过渡​

除了通过 v-if / v-show 切换一个元素,我们也可以通过 v-if / v-else / v-else-if 在几个组件间进行切换,只要确保任一时刻只会有一个元素被渲染即可:

template

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

过渡模式​

在之前的例子中,进入和离开的元素都是在同时开始动画的,因此我们不得不将它们设为 position: absolute 以避免二者同时存在时出现的布局问题。

然而,很多情况下这可能并不符合需求。我们可能想要先执行离开动画,然后在其完成之后再执行元素的进入动画。手动编排这样的动画是非常复杂的,好在我们可以通过向 <Transition> 传入一个 mode prop 来实现这个行为:

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

将之前的例子改为 mode="out-in" 后是这样:

Click to cycle through states:

<Transition> 也支持 mode="in-out",虽然这并不常用。

组件间过渡​

<Transition> 也可以作用于动态组件​​​​​​​之间的切换:

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

动态过渡​

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

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

这个特性的用处是可以提前定义好多组 CSS 过渡或动画的 class,然后在它们之间动态切换。

你也可以根据你的组件的当前状态在 JavaScript 过渡钩子中应用不同的行为。最后,创建动态过渡的终极方式还是创建可复用的过渡组件​​​​​​​,并让这些组件根据动态的 props 来改变过渡的效果。掌握了这些技巧后,就真的只有你想不到,没有做不到的了。

使用 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 组件有两个不同的元素在它们之间进行过渡。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/810565.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从大量数据到大数据,King’s SDMS仪器数据采集及科学数据管理系统的应用

对于实验室或检测机构&#xff0c;仪器设备是所有业务开展的基础&#xff0c;数据则是核心命脉&#xff0c;而传统的仪器设备原始数据收集方式&#xff0c;效率低耗时长、操作流程不规范、不易保存与查找、错误率高、易篡改等成了制约检测机构持续高速发展的瓶颈和弊端&#xf…

单例19c RMAN数据迁移方案

一、环境说明 源库 目标库 IP 192.168.37.200 192.168.37.202 系统版本 RedHat 7.9 RedHat 7.9 数据库版本 19.3.0.0.0 19.3.0.0.0 SID beg beg hostname beg rman 数据量 1353M 说明:源库已经创建数据库实例&#xff0c;并且存在用户kk和他创建的表空间…

新规来了!智能音视频技术重塑信贷体验

近日&#xff0c;国家金融监督管理总局发布《固定资产贷款管理办法》《流动资金贷款管理办法》《个人贷款管理办法》&#xff08;以下简称“三个办法”&#xff09;。 具体来看&#xff0c;新规明确了以下要求&#xff1a; 1、明确视频面签、电子签约要求 允许商业银行通过视…

Oracle 19c RAC集群相关日志

1.DB日志&#xff08;数据库日志&#xff09; Redo Log&#xff08;重做日志&#xff09;&#xff1a; 在Oracle数据库中&#xff0c;重做日志记录了数据库发生的所有修改操作&#xff0c;包括数据的插入&#xff0c;更新和删除。在RAC的环境中&#xff0c;每个实例都有自己的重…

Ubuntu22.04搭建CLion C++开发环境

Ubuntu22.04搭建CLion C开发环境 文章目录 Ubuntu22.04搭建CLion C开发环境1.首先下载CLion2.配置c环境3.创建快捷方式Reference 1.首先下载CLion 进入官网https://www.jetbrains.com/clion/download/#sectionlinux 然后进入自己存放这个压缩包的路径中&#xff0c; sudo mkd…

SQLite从出生到现在(发布历史记录)(二十二)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;从 SQLite 3.5.9 迁移到 3.6.0&#xff08;二十一&#xff09; 下一篇&#xff1a;SQLite—系列文章目录 引言&#xff1a; SQLite拥有别人无法比拟的装机量&#xff0c;究竟什么成就了SQLite呢&#xff0c;本…

最长公共子序列、最长上升子序列(LCS与LIS)算法

最长公共子序列、最长上升子序列(LCS与LIS) 最长公共子序列(LCS) #include <bits/stdc.h> using namespace std; #define int long long const int N 1e39; int a[N],b[N],dp[N][N]; signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int n,m;cin>>…

大文件传输之为啥传输过程中出现宽带不足的情况

在当今数字化时代&#xff0c;大文件传输已成为企业日常运营的关键环节。然而&#xff0c;许多企业在传输大文件时经常面临宽带不足的问题&#xff0c;这不仅影响了工作效率&#xff0c;还可能导致业务机会的丧失。本文将探讨大文件传输过程中宽带不足的原因&#xff0c;以及镭…

【数据结构】稀疏矩阵的快速转置

【数据结构】稀疏矩阵的转置&#xff08;普通转置 和 快速转置&#xff09; 目录 【数据结构】稀疏矩阵的转置&#xff08;普通转置 和 快速转置&#xff09;三元表稀疏矩阵的转置方法一&#xff08;普通转置&#xff09;复杂度为O(T.muT.nu)方法二&#xff1a;快速转置 复杂度…

聚道云软件连接器助力企业实现CRM与税票系统对接,提升财务管理效率

一、客户介绍&#xff1a;行业翘楚&#xff0c;寻求数字化升级 某企业作为行业内的佼佼者&#xff0c;始终站在市场前沿&#xff0c;不断探索数字化转型的新路径。近年来&#xff0c;随着业务规模的扩大&#xff0c;该企业对于客户关系管理&#xff08;CRM&#xff09;与税务电…

数据分析python代码——数据填充

在Python中&#xff0c;我们通常使用pandas库来处理和分析数据。数据填充是数据预处理的一个重要步骤&#xff0c;用于处理数据中的缺失值。以下是使用pandas库进行数据填充的示例代码&#xff1a; 在数据分析中&#xff0c;处理缺失值&#xff08;空值&#xff09;是一个重要…

AI预测体彩排3第1弹【2024年4月12日预测--第1套算法开始计算第1次测试】

前面经过多个模型几十次对福彩3D的预测&#xff0c;积累了一定的经验&#xff0c;摸索了一些稳定的规律&#xff0c;有很多彩友让我也出一下排列3的预测结果&#xff0c;我认为目前时机已成熟&#xff0c;且由于福彩3D和体彩排列3的玩法完全一样&#xff0c;我认为3D的规律和模…

【竞技宝】LOL:bin卡牌完美牵制 BLG击败TES晋级春决

北京时间2024年4月12日,英雄联盟LPL2024春季季后赛继续进行,昨天迎来四强赛胜者组决赛BLG对阵TES。本场比赛双方前几局有来有回战至2-2平,决胜局bin的上单卡牌中期完美牵制了TES,后期孤身一人偷家成功,最终BLG3-2击败TES晋级春决。以下是本场比赛的详细战报。 第一局: 首局比赛…

数字乡村可视化大数据-DIY拖拽式设计

DIY拖拽式大数据自由设计万村乐可视化大数据V1.0 随着万村乐数字乡村系统的广泛使用&#xff0c;我们也接收到了客户的真实反馈&#xff0c;最终在公司的决定下&#xff0c;我们推出了全新的可视化大数据平台V1.0版本&#xff0c;全新的可视化平台是一个通过拖拽配置生成可视化…

网络流量分析与控制

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计5477字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

爬虫现在还有那么吃香嘛?

Python 作为一种广泛应用的编程语言&#xff0c;在 Web 开发、大数据开发、人工智能开发和嵌入式开发等领域都有着重要的应用。 Python 的易学性、清晰性和可移植性等特点使它得到很多技术人士的喜爱。对于数据科学和机器学习领域的程序员来说&#xff0c;Python 提供了强大的…

YOLOV5 分类:利用yolov5进行图像分类

1、前言 之前介绍了yolov5的目标检测示例,这次将介绍yolov5的分类展示 目标检测:YOLOv5 项目:训练代码和参数详细介绍(train)_yolov5训练代码的详解-CSDN博客 yolov5和其他网络的性能对比 yolov5分类的代码部分在这 2、数据集准备 yolov5分类的数据集就是常规的摆放方式…

vue 文件预览

<template><div><p>打开新页面预览文件</p><div v-for"(item,index) in list" :key"index"><el-link type"primary" click"handleOpen(item.url)">{{item.name}}</el-link></div><…

物联网SaaS平台

在信息化、智能化浪潮席卷全球的今天&#xff0c;物联网SaaS平台作为推动工业数字化转型的重要工具&#xff0c;正日益受到广泛关注。那么&#xff0c;物联网SaaS平台究竟是什么&#xff1f;HiWoo Cloud作为物联网SaaS平台又有哪些独特优势&#xff1f;更重要的是&#xff0c;它…