Vue3 中实现过渡动画的几种方式?

前言

首先抛开 vue 本身,假设需要给某个 Dom 元素实现一些过渡动画,那么下面这些事是必须的:

  • 实现目标元素不同时刻下的样式,常见做法就是抽取在不同的 css 选择器中
  • 根据不同时刻切换不同的 css 选择器以达到样式的变化
  • 设置样式过度的方式和时间,如:transition: all .5s ease

而在 vue 中实现过渡动画,那就不得不提到其内置的 transition 组件,而 transition 组件帮我们实现了第一件事,就是对组件不同时刻设置不同的 css 选择器,甚至于可以对这个选择器进行自定义,因此,我们只需要完成后面两件事即可,当然这里对 transition 组件的用法就不过多进行介绍.

1643034725(1).png

当然这里的实现动画的方式,会从下面几个方面来实现:

  • CSS3 transition 属性
  • CSS3 @keyframes 帧动画
  • 第三方库 animate.css
  • 第三方库 gsap —— GreenSock Animation Platform,在官方文档中有提及的

<transition> 组件 + CSS3 transition 属性

话不多说,直接来实现一个简单的 显示/隐藏 的过渡动画:

  • 显示时:从左侧滑入,且透明度增大
  • 隐藏时:从右侧滑出,且透明度减小
// toggle.vue
<script setup lang="ts">
import { ref } from 'vue'const isShow = ref(true)const toggle = () => {isShow.value = !isShow.value
}</script><template><transition name="fade"><h1 v-if="isShow">this is h1 content!</h1></transition><div><button @click="toggle">toggle</button></div>
</template><style>
.fade-enter-from,
.fade-leave-to {opacity: 0;
}.fade-enter-from {transform: translateX(-30px);
}.fade-enter-to ,
.fade-leave-to {transform: translateX(30px);
}.fade-enter-to,
.fade-leave-from {opacity: 1;
}.fade-enter-active,
.fade-leave-active {transition: all .5s ease;
}h1 {width: 300px;margin: 10px auto;
}
</style>

<transition> 组件 + CSS3 @keyframes 帧动画

css 中除了使用 transition 属性实现不同样式间的过渡,也可以直接使用 @keyframes 来实现帧动画.

// hang.vue
<script setup lang="ts">
import { ref } from 'vue'const isShow = ref(true)const hang = () => {isShow.value = !isShow.value
}</script><template><transition name="fade"><h1 v-if="isShow">this is h1 content!</h1></transition><div><button @click="hang">trigger</button></div>
</template><style>
.fade-enter-active {animation: hang 0.5s 1 ease;
}.fade-leave-active {animation: hang 0.5s 1 ease reverse;
}@keyframes hang {0% {transform: translateY(30px) rotateZ(30deg);opacity: 0;}25% {transform: translateY(24px) rotateZ(24deg);opacity: 0.3;}50% {transform: translateY(18px) rotateZ(18deg);opacity: 0.6;}75% {transform: translateY(12px) rotateZ(12deg);opacity: 0.8;}100% {transform: translateY(-5px) rotateZ(0deg);opacity: 1;}
}h1 {width: 300px;margin: 10px auto;
}
</style>

<transition> 组件 + 第三方库 animate.css

直接使用 animate.css 中对应效果的动画名,配合 animation 属性进行使用即可.

对应的效果和动画名可通过 animat.style 效果预览 查看

animate.gif

// animate.vue
<script setup lang="ts">
import { ref } from 'vue'
import './animate.css'const isShow = ref(true)const hang = () => {isShow.value = !isShow.value
}</script><template><transition name="fade"><h1 v-if="isShow">this is h1 content!</h1></transition><div><button @click="hang">trigger</button></div>
</template><style>
.fade-enter-active {animation: flip 0.5s 1 ease;
}.fade-leave-active {animation: flip 0.5s 1 ease reverse;
}h1 {width: 300px;margin: 10px auto;
}
</style>

<transition> 组件 + 第三方库 gsap

通过上面几个简单的动画例子,其实不难发现,无论是自己实现动画,还是使用已有的 css 样式库都有一个缺点,就是不够灵活,比如:某些 css 属性值只能是一个不变的值

如果有些场景需要一些更复杂和灵活的 css 样式,那么显然前面提到的方式并不符合实际需求,换句话说,如果需要在 js 中实现样式的过渡,以及设置动态的 css 样式属性值时,就有必要使用一些第三方库,如:gsap,帮助我们更方便的实现需求.

// gsap.vue
<script setup>
import { ref } from "vue";
import gsap from "gsap";let timeScaleTween = null;const enter = (el) => {const tl = gsap.timeline(),atom = el,dur = 2,del = 0.5;tl.fromTo(".electron",{ rotationX: 90 },{rotationZ: -360,rotationX: 90,ease: "none",duration: dur,stagger: {each: -del,repeat: -1,},},0);tl.to(".path",{rotationZ: 360,ease: "none",duration: dur,stagger: {each: -del,repeat: -1,},},0);// Add a rotation to the whole atomgsap.set(atom, { transformOrigin: "center center" });gsap.to(atom, { rotation: 360, ease: "none", repeat: -1, duration: 300 });// Skip the loadingtl.progress(0.9999);timeScaleTween = gsap.to(tl, {duration: 0.75,timeScale: 0.1,paused: true,});
};const slow = () => {timeScaleTween.play()
}const reverse = () => {timeScaleTween.reverse()
}const isShow = ref(false);const show = () => {isShow.value = true
};
</script><template><transition name="fade" @enter="enter"><div class="atom" v-if="isShow"><div class="orbit"><div class="path"><div class="electron"></div></div></div><div class="orbit"><div class="path"><div class="electron"></div></div></div><div class="orbit"><div class="path"><div class="electron"></div></div></div><div class="orbit"><div class="path"><div class="electron"></div></div></div><div class="nucleus"></div></div></transition><div><button @click="show">show</button><button @click="slow">slow</button><button @click="reverse">reverse</button></div>
</template><style>
@import url("https://fonts.googleapis.com/css?family=Signika+Negative:300,400&display=swap");
body {font-family: "Signika Negative", sans-serif;font-weight: 300;background: grey;overflow: hidden;color: white;text-align: center;
}.atom {position: absolute;top: 50%;left: 50%;width: 300px;height: 300px;perspective: 1000;margin-left: -170px;margin-top: -146px;transform-style: preserve-3d;
}.nucleus {position: absolute;top: 50%;left: 50%;margin: -10px 0 0 -10px;width: 25px;height: 25px;border-radius: 50%;background: #272727;
}.orbit {position: absolute;top: 0;left: 0;width: 300px;height: 300px;border-radius: 300px;border: 5px solid #ccc;transform-style: preserve-3d;transform: rotateX(80deg) rotateY(20deg);
}.orbit:nth-child(2) {transform: rotateX(80deg) rotateY(70deg);
}
.orbit:nth-child(3) {transform: rotateX(80deg) rotateY(-20deg);
}
.orbit:nth-child(4) {transform: rotateX(80deg) rotateY(-50deg);
}.path {width: 300px;height: 300px;position: relative;transform-style: preserve-3d;
}.electron {position: absolute;top: -5px;left: 50%;margin-left: -5px;width: 10px;height: 10px;border-radius: 10px;background: #ccc;
}
button{margin: 10px;
}
</style>

最后

以上就通过四种方式实现了一些简单动画,但其实在 vue 中实现动画也不一定要使用 transition 组件,具体场景还是得具体分析.

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

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

相关文章

Linux 中,flock 对文件加锁

在Linux中&#xff0c;flock是一个用于对文件加锁的实用程序&#xff0c;它可以帮助协调多个进程对同一个文件的访问&#xff0c;避免出现数据不一致或冲突等问题。以下是对flock的详细介绍&#xff1a; 基本原理 flock通过在文件上设置锁来控制多个进程对该文件的并发访问。…

【华为HCIP实战课程二十七】中间到中间系统协议IS-IS Hello报文,网络工程师

一、IS-IS术语 1、IIH: ISIS hello 报文,相当于OSPF的Hello报文,hello-interval 10s, hold-time 30s 2、LSP:链路状态数据单元,类似OSPF的LSA,携带路由信息(L1和L2的LSP) 3、SNP:系列号PDU (1)、PSNP:部分序列号协议数据单元,类似OSPF的ACK,Request (2)、CSNP:…

python-opencv给图片或视频去水印

文章目录 引言inpaint函数的使用方法鼠标事件回调函数cv2.setMouseCallback介绍去水印步骤实现代码 引言 本文主要基于cv2.inpaint函数实现图片的水印去除。 inpaint函数基于图像修复算法&#xff0c;通过对缺陷区域周围像素的分析和插值&#xff0c;生成合适的像素值来填充缺…

渗透测试-百日筑基—文件上传篇特征截断渲染%00绕过——下篇

目录 day10-渗透测试文件上传篇&绕过&特征&截断&渲染 一、黑名单大小写绕过代码分析 1、获取文件后缀名进行判断&#xff0c;如果后缀在这个字典里就禁止上传。 2、黑名单大小写绕过攻击 二、利用 windows 系统特征绕过上传 1、windows 系统特征绕过漏洞…

C语言 | Leetcode C语言题解之第522题最长特殊序列II

题目&#xff1a; 题解&#xff1a; #define MAX(a, b) ((a) > (b) ? (a) : (b))bool is_subseq(const char *s, const char *t) {int pt_s 0, pt_t 0;int len_s strlen(s), len_t strlen(t);while (pt_s < len_s && pt_t < len_t) {if (s[pt_s] t[pt_…

STM32CUBEMX安富莱STM32-V6开发板使用FMC驱动SDRAM芯片MT48LC4M32B2TG

文章的目的是快速使用SDRAM芯片&#xff0c;没有详细讲解原理。 1、环境&#xff1a; 单片机&#xff1a;STM32F429VIT6 CUBE版本&#xff1a;STM32CUBMX 6.12.1 编译&#xff1a;KEIL MDK 硬件&#xff1a;安富莱STM32-V6开发板 SDRAM芯片&#xff1a;MT48LC4M32B2TG 2、配…

为什么QNAP威联通NAS的APP center无法安装APP?

创作立场&#xff1a;原创不易&#xff0c;拒绝搬运~ hello大家好&#xff0c;我是你们的老伙伴&#xff0c;稳重的大王~ 如题&#xff0c;大王带你一起来排查一下&#xff0c;可能遇到的问题。如有帮助&#xff0c;请给个关注鼓励&#xff0c;互谢~ 1 首先&#xff0c;安装…

人工智能算法之粒子群优化算法

人工智能算法之粒子群优化算法 粒子群优化算法&#xff08;PSO&#xff09;是一种群体智能优化算法&#xff0c;由Kennedy和Eberhart在1995年提出&#xff0c;灵感来源于鸟群、鱼群等生物群体行为。PSO通过群体中个体的交互及对周围环境的感知&#xff0c;快速找到最优解。PSO算…

【深入浅出】深入浅出transformer(附面试题)

本文的目的是为了帮助大家面试transformer&#xff0c;会结合我的面试经历以及看法去讲解transformer&#xff0c;并非完整的技术细致讲解&#xff0c;介意请移步。 结构 提到transformer网络模型&#xff0c;大家脑海中是否有这张图呢&#xff1f; 这是网络结构中经典的编解…

net 获取本地ip地址,net mvc + net core 两种

net mvc public static string GetIP(HttpRequestBase request){// 尝试获取 X-Forwarded-For 头string result request.Headers["X-Forwarded-For"]?.Split(,).FirstOrDefault()?.Trim();if (string.IsNullOrEmpty(result)){// 获取用户的 IP 地址result reques…

Handler、Looper、message进阶知识

Android Handler、Looper、Message的进阶知识 在Android开发中&#xff0c;Handler、Looper和Message机制是多线程通信的核心。为了深入理解并优化它们的使用&#xff0c;尤其是在高并发和UI性能优化中&#xff0c;可以利用一些高级特性。 1. Handler的高阶知识 Handler在基本…

开源一款基于 JAVA 的仓库管理系统,支持三方物流和厂内物流,包含 PDA 和 WEB 端的源码

大家好&#xff0c;我是一颗甜苞谷&#xff0c;今天分享一款基于 JAVA 的仓库管理系统,支持三方物流和厂内物流,包含 PDA 和 WEB 端的源码。 前言 在当前的物流仓储行业&#xff0c;企业面临着信息化升级的迫切需求&#xff0c;但往往受限于高昂的软件采购和维护成本。现有的…

Sigrity Power SI Resonance analysis模式如何进行谐振分析操作指导

Sigrity Power SI Resonance analysis模式如何进行谐振分析操作指导 Sigrity Power SI可以方便快捷的进行谐振分析,谐振分析的目的是为了分析电源地平面组成的腔体的谐振频率以及谐振幅度,让频率在谐振频率附近的信号避开谐振腔,以及添加相应的电容来降低谐振峰值. 仍然以这…

vue特性

Vue.js是一套构建用户界面的渐进式框架&#xff0c;其特性主要包括以下几点&#xff1a; MVVM模式 Vue.js采用了MVVM&#xff08;Model-View-ViewModel&#xff09;的设计模式。在这种模式下&#xff0c;Model代表数据模型&#xff0c;View代表用户界面&#xff0c;ViewModel…

【AI开源项目】FastGPT- 快速部署FastGPT以及使用知识库的两种方式!

文章目录 一、FastGPT大模型介绍1. 开发团队2. 发展史3. 基本概念 二、FastGPT与其他大模型的对比三、使用 Docker Compose 快速部署 FastGPT1、安装 Docker 和 Docker Compose&#xff08;1&#xff09;. 安装 Docker&#xff08;2&#xff09;. 安装 Docker Compose&#xff…

Kubernetes实战——DevOps集成SpringBoot项目

目录 一、安装Gitlab 1、安装并配置Gitlab 1.1 、下载安装包 1.2、安装 1.3、修改配置文件 1.4、更新配置并重启 2、配置 2.1、修改密码 2.2、禁用注册功能 2.3、取消头像 2.4、修改中文配置 2.5、配置 webhook 3、卸载 二、安装镜像私服Harbor 1、下载安装包 2、…

多项目管理复杂性对企业的影响

在现代企业中&#xff0c;多项目管理已成为提升竞争力的关键策略。然而&#xff0c;资源分配冲突、沟通协调难题、优先级排序复杂等因素使得多项目管理充满挑战。资源分配冲突尤其突出&#xff0c;因为在多个项目同时进行时&#xff0c;有限的资源需要在不同项目间进行合理分配…

利用EasyExcel实现简易Excel导出

目标 通过注解形式完成对一个方法返回值的通用导出功能 工程搭建 pom <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance&qu…

Mac OS 搭建MySQL开发环境

Mac OS 搭建MySQL开发环境 文章目录 Mac OS 搭建MySQL开发环境一、安装Mysql&#xff1a;二、配置环境变量三、安装Navicat 本地环境&#xff1a; Mac OS Sequoia15.0.1&#xff08;M3 Max) 目标状态&#xff1a; 下载安装Mysql&#xff0c;配置相关环境。 一、安装Mysql&…

关于springboot跨域与拦截器的问题

今天写代码的时候遇到的一个问题&#xff0c;在添加自己设置的token拦截器之后&#xff0c;报错&#xff1a; “ERROR Network Error AxiosError: Network Error at XMLHttpRequest.handleError (webpack-internal:///./node_modules/axios/lib/adapters/xhr.js:112:14) at Axi…