Vue 入门到实战 五

5章 过渡与动画

目录

5.1 单元素/组件过渡

5.1.1 过渡class

5.1.2 CSS 过渡

5.1.3 CSS 动画

5.1.4 同时使用过渡和动画

5.1.5 JavaScript 钩子方法

5.2 多元素/组件过渡

5.2.1 多元素过渡

5.2.2 多组件过渡

5.3 列表过渡

5.3.1 列表的普通过渡

5.3.2 列表的平滑过渡

5.3.3 列表的变换过渡

5.3.4 多维列表的过渡


5.1 单元素/组件过渡

Vue在插入、更新或者移除 DOM 时,提供多种不同方式的过渡效果(一个淡入淡出的效果)。在条件渲染(使用v-if)、条件展示(使用v-show)、动态组件、组件根节点等情形中,可以给任何元素和组件添加进入/离开过渡。Vue提供了内置的过渡封装组件<transition>,该组件用于包裹要实现过渡效果的组件。具体语法如下:

<transition name = "过渡名称">

  <!--要实现过渡效果的组件-->

</transition>

5.1.1 过渡class

总结起来就分为 进入 和 离开 动画的 初始状态、生效状态、结束状态,具体如下:

  • v-enter-from
    • 进入 动画的 起始状态
    • 在元素插入之前添加,在元素插入完成后的 下一帧移除
  • v-enter-active
    • 进入 动画的 生效状态,应用于整个进入动画阶段
    • 在元素被插入之前添加,在过渡或动画完成之后移除
    • 这个 class 可以被用来定义进入动画的持续时间、延迟与速度曲线类型
  • v-enter-to
    • 进入 动画的 结束状态
    • 在元素插入完成后的下一帧被添加 (也就是 v-enter-from 被移除的同时),在过渡或动画完成之后移除
  • v-leave-from
    • 离开 动画的 起始状态
    • 在离开过渡效果被触发时立即添加,在一帧后被移除
  • v-leave-active
    • 离开 动画的 生效状态,应用于整个离开动画阶段
    • 在离开过渡效果被触发时立即添加,在 过渡或动画完成之后移除
    • 这个 class 可以被用来定义离开动画的持续时间、延迟与速度曲线类型
  • v-leave-to
    • 离开 动画的 结束状态
    • 在一个离开动画被触发后的 下一帧 被添加 (即 v-leave-from 被移除的同时),在 过渡或动画完成之后移除

其中的 v 前缀是允许修改的,可以 <Transition> 组件传一个 name 的 prop 来声明一个过渡效果名,如下就是将 v 前缀修改为 modal 前缀:

<div id="app"><button @click="show = !show">点我,我就渐渐的离开、渐渐的来。</button><transition name="fade"><p v-show="show" :style="styleobj">动画实例</p></transition>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {show: true,styleobj: {fontSize: '30px',color: 'red'}}}})app.mount('#app')
</script>
<style>.fade-enter-active,.fade-leave-active {transition: opacity 2s ease;}.fade-enter-from,.fade-leave-to {opacity: 0;}
</style>

5.1.2 CSS 过渡

常用的过渡一般都是CSS过渡。CSS过渡,顾名思义也就是使用过渡class定义CSS实现过渡效果。

5-2】使用过渡class定义图片的进入和离开动画效果,运行效果如图5.2所示。

 

<div id="app"><button @click="show = !show">切换显示图片</button><transition name="slide-img"><p v-if="show"><img src="99.jpg"/></p></transition>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {show: true}}})app.mount('#app')
</script>
<style>.slide-img-enter-active {	    transition: all 5s ease-out; //ease-out 规定以慢速结束的过渡,进入界面需要延迟5秒才会显示整个图片}.slide-img-leave-active {transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);}.slide-img-enter-from,.slide-img-leave-to {  transform: rotateX(45deg);   //X轴45°旋转transform: rotateY(45deg);  transform: rotateZ(45deg);  transform: rotate3d(1, 1, 1, 45deg);opacity: 0;}
</style>

5.1.3 CSS 动画

CSS动画与CSS过渡用法相同,区别是在动画中v-enter类名在节点插入DOM后不会立即被删除,而是在animationend(动画结束)事件触发时删除。

1. 基本概念
CSS 动画由两个主要部分组成:

@keyframes:定义动画的关键帧,指定动画在不同时间点的状态。
     animation:应用于元素的属性,控制动画的播放、持续时间、延迟等。
2. @keyframes 关键帧的定义
@keyframes 定义了动画的各个关键帧,控制元素的从一个状态到另一个状态的转换过程。

5-3】使用@keyframes定义图片的动画规则,运行效果如图5.3所示。

<div id="app"><button @click="show = !show">切换图片动画</button><transition name="bounce-img"><p v-if="show"><img src="99.jpg" /></p></transition>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {show: true}}})app.mount('#app')
</script>
<style>.bounce-img-enter-active {animation: bounce-in 0.8s;}.bounce-img-leave-active {animation: bounce-in 0.8s reverse;}@keyframes bounce-in {0% {transform: scale(0);}50% {transform: scale(1.25);}100% {transform: scale(1);}}
</style>

 

5.1.4 同时使用过渡和动画

在一些应用场景中,需要给一个元素同时设置过渡和动画,比如 animation 很快的被触发并完成,而 transition 效果还没结束。这时,需要使用 type属性并设置 animation transition值来明确声明需要Vue监听的类型。

<transition> 组件的 duration prop上可显性定义过渡持续时间(以毫秒计),比如,定制进入和移出的持续时间:<transition :duration="{ enter:1000, leave: 2000 }">...</transition>。还可以通过appear属性设置DOM节点在初始渲染的过渡(页面加载的初次过渡动画):<transition appear>...</transition>

<head><!--使用第三方动画库--><link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/animate.css/3.7.2/animate.min.css">
</head>
<!--使用type='transition'以transition过渡时长为准,
即fade-enter-active和fade-leave-active定义的时长,
或者绑定属性:duration="{enter:5000,leave:5000}"自定义时长,
type='transition'与:duration="5000" 二选一;
使用animate.css必须使用vue的 enter-active-class 和 leave-active-class,
后面紧跟animated类名和想使用的动画名称;
appear,appear-active-class实现页面加载的初次动画(初始渲染过渡)。-->
<div id="app"><transition name='fade' appear :duration="{enter:5000,leave:5000}"enter-active-class='animated swing fade-enter-active' leave-active-class='animated shake fade-leave-active'appear-active-class='animated swing' ><div v-if='show'>hello world</div></transition><button @click="handleClick">切换显示</button>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {show: true}},methods: {handleClick() {this.show = !this.show}}})app.mount('#app')
</script>
<style type="text/css">.fade-enter,.fade-leave-to {opacity: 0;}.fade-enter-active,.fade-leave-active {transition: opacity 5s;}div {font-size: 40px;margin: 50px auto;}
</style>

5.1.5 JavaScript 钩子方法

 

<div id="app"><button @click="show = !show" class="btn">添加到购物车</button><transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter"><div v-if="show" class="ball"></div></transition>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {show: false}},methods: {//el表示将要执行动画的DOM元素,beforeEnter表示动画开始前beforeEnter(el) {//设置元素动画开始前的起始位置el.style.transform = "translate(0, 0)"},enter(el, done) {//返回元素的宽度,强制动画刷新el.offsetWidth//设置元素动画开始之后的样式,设置完成之后状态el.style.transform = "translate(200px, -200px)"el.style.transition = "all 3s cubic-bezier(0, 0.54, 0.55, 1.18)"//done这里代表afterEnter方法的引用done()},afterEnter(el) {//动画完成后,调用该方法this.show = !this.show}}})app.mount('#app')
</script>
<style>.ball {width: 30px;height: 30px;border-radius: 50%;background-color: green;position: absolute;z-index: 99;top: 200px;left: 100px;}.btn {position: absolute;top: 200px;}
</style>

5.2 多元素/组件过渡

5.2.1 多元素过渡

对于原生元素可以使用v-if/v-else实现多元素过渡。最常见的多元素过渡是一个列表和描述这个列表为空消息的元素:

<transition>

  <table v-if="items.length > 0">

  <!-- ... -->

  </table>

  <p v-else>没有列表内容</p>

</transition>

实际上,通过使用多个v-if或将单个元素绑定到一个动态属性上,可以在任意数量的元素之间进行过渡。

<div id="app"><button @click="handleClick('saved')">显示Edit</button>&nbsp;&nbsp;<button @click="handleClick('edited')">显示Save</button>&nbsp;&nbsp;<button @click="handleClick('editing')">显示Cancel</button><br><br><transition name="fade" mode="out-in"><!--这里使用key让vue区分相同标签名元素,触发过渡--><button :key="docState">{{ buttonMessage }}</button></transition>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {docState: ''}},methods: {handleClick(myVal) {this.docState = myVal}},computed: {buttonMessage() {switch (this.docState) {case 'saved': return 'Edit'case 'edited': return 'Save'case 'editing': return 'Cancel'default: return '初始按钮'}}}})app.mount('#app')
</script>
<style type="text/css">.fade-enter-from,.fade-leave-to {opacity: 0;}.fade-enter-active,.fade-leave-active {transition: opacity 5s ease;}
</style>

5.2.2 多组件过渡

可以使用多组件过渡将多个组件包装成动态组件的效果。

5-7】设计一个类似于选项卡的页面,单击“多组件过渡按钮”将 “登录子组件”和“注册子组件”进行切换。

<div id="app"><button @click="show">多组件过渡按钮</button><transition name="check" mode="out-in"><!-- is用来展示的template组件,mode组件切换的模式,name过渡的前缀,component占位符表示展示的组件 --><component :is="view"></component></transition>
</div>
<!-- 登录子组件 -->
<template id="login"><div><h1>登录子组件</h1></div>
</template>
<!-- 注册子组件 -->
<template id="register"><div><h1>注册子组件</h1></div>
</template>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {view: 'login'}},methods: {show: function () {if (this.view == "login") {this.view = "register"} else {this.view = "login"}}},components: {login: {template: "#login"},register: {template: "#register"}}})app.mount('#app')
</script>
<style type="text/css">.check-enter-from,.check-leave-to {opacity: 0;}.check-enter-active,.check-leave-active {transition: opacity 5s ease;}
</style>

5.3 列表过渡

对于列表元素,可使用<transition-group>组件进行过渡。<transition-group>组件具有以下几个特点:

1、不同于 <transition>组件,它默认以<span>元素渲染。

2、过渡模式不可用,因为不再相互切换特有的元素。

3、内部元素需要提供唯一的key属性值。

4CSS过渡类将会应用在组件内部的元素中,而不是组件本身。

5.3.1 列表的普通过渡

5.3.2 列表的平滑过渡

在例5-8中,当添加和移除元素时,周围元素将瞬间移动到它们的新布局位置,而不是平滑的过渡。

<transition-group> 组件不仅可以进入和离开列表过渡,还可以通过v-move特性改变定位,进行平滑过渡。v-move特性像之前的类名一样,可以通过name属性来自定义前缀。

<div id="list-demo" class="demo"><button @click="add">添加元素</button>&nbsp;<button @click="remove">移除元素</button><transition-group name="list" tag="p"><span v-for="item in items" :key="item" class="list-item">{{item}}</span></transition-group>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {items: [1, 2, 3, 4, 5, 6, 7, 8, 9],nextNum: 10}},methods: {randomIndex() {return Math.floor(Math.random() * this.items.length)},add() {this.items.splice(this.randomIndex(), 0, this.nextNum++)},remove() {this.items.splice(this.randomIndex(), 1)}}})app.mount('#list-demo')
</script>
<style>.list-item {display: inline-block;margin-right: 10px;}.list-enter-active,.list-leave-active {transition: all 3s;}.list-enter,.list-leave-to {opacity: 0;transform: translateY(30px);}
</style>

5-9】列表的平滑过渡,可以在例5-8的基础上,做出如下改进:1、增加.list-move样式,使元素在进入时实现过渡效果;2、在.list-leave-active中设置绝对定位,使元素在离开时实现过渡效果。

<div id="list-demo" class="demo"><button @click="add">添加元素</button>&nbsp;<button @click="remove">移除元素</button><transition-group name="list" tag="p"><span v-for="item in items" :key="item" class="list-item">{{item}}</span></transition-group>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {items: [1, 2, 3, 4, 5, 6, 7, 8, 9],nextNum: 10}},methods: {randomIndex() {return Math.floor(Math.random() * this.items.length)},add() {this.items.splice(this.randomIndex(), 0, this.nextNum++)},remove() {this.items.splice(this.randomIndex(), 1)}}})app.mount('#list-demo')
</script>
<style>.list-item {display: inline-block;margin-right: 10px;}.list-move,.list-enter-active,.list-leave-active {transition: 3s;}.list-leave-active {position: absolute;}.list-enter,.list-leave-to {opacity: 0;transform: translateY(30px);}
</style>

5.3.3 列表的变换过渡

利用move属性,进行变换过渡,即一个列表中的列表项既不增加也不减少,只是不断地变换其位置。

5-10】列表的变换过渡。

<div id="list-demo" class="demo"><button @click="shuffle">变换过渡</button><transition-group name="list" tag="ul"><li v-for="item in items" :key="item">{{item}}</li></transition-group>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {items: [1, 2, 3, 4, 5, 6, 7, 8, 9],nextNum: 10}},methods: {shuffle() {this.items = this.items.sort(() => { return Math.random() - 0.5; })}}})app.mount('#list-demo')
</script>
<style>.list-move {transition: transform 3s;}
</style>

5.3.4 多维列表的过渡

FLIP动画不仅可以实现单列表过渡,多维网格列表的过渡也同样简单。

5-11】多维网格列表的过渡。

<div id="list-demo" class="demo"><button @click="shuffle">多维列表变换</button><transition-group name="cell" tag="div" class="container"><span v-for="cell in cells" :key="cell.id" class="cell">{{ cell.number }}</span></transition-group>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {cells: Array.apply(null, { length: 81 }).map(function (_, index) {return {id: index,number: index % 9 + 1}})}},methods: {shuffle() {this.cells = this.cells.sort(() => { return Math.random() - 0.5; })}}})app.mount('#list-demo')
</script>
<style>.container {width: 270px;margin-top: 10px;line-height: 30px;text-align: center;}.cell {display: inline-block;width: 30px;height: 30px;outline: 1px solid #aaa;}.cell-move {transition: 3s;}
</style>

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

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

相关文章

L2TP实验

一、拓朴图 二、实验配置 1.基础配置 1.1接口IP及服务配置 [PPPoE Client]interface GigabitEthernet 0/0/0 [PPPoE Client-GigabitEthernet0/0/0]service-manage all permit [NAS]interface GigabitEthernet 0/0/0 [NAS-GigabitEthernet0/0/0]ip add 192.168.0.2 24 [NAS-Gi…

简单实用!百度AI + Raphael AI = 免费生图

简单实用&#xff01;百度AI Raphael AI 免费生图 -- ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/b55eda9141d34697b05db0cd60f62b75.png#pic_center) 第一步&#xff1a;下载或截取一些好看的图片当参考图片 第二步&#xff1a;用百度AI描述你想要的图片&…

aws(学习笔记第三十四课) dockerized-app with asg-alb

文章目录 aws(学习笔记第三十四课) dockerized-app with asg-alb学习内容&#xff1a;1. 整体架构1.1 代码链接1.2 代码手动修改部分1.2.1 rds_stack.py1.2.2 efs_stack.py1.2.3 asg_stack.py1.2.4 userdata.sh 1.2 整体架构 2.代码解析2.1 全体app.py2.2 NetworkStatck网络2.3…

面试总结之 Glide自定义的三级缓存策略

一、为什么需要三级缓存&#xff1f; 在移动应用开发中&#xff0c;图片加载性能直接影响用户体验。根据 Google 统计&#xff0c;图片加载延迟超过 1 秒会导致 32% 的用户流失。传统图片加载方案存在以下痛点&#xff1a; 内存占用高&#xff1a;未压缩的大图直接占用大量内…

用Python实现交互式数据可视化:从基础图表到动态仪表板

用Python实现交互式数据可视化&#xff1a;从基础图表到动态仪表板 一、项目背景 本文将通过一个完整的Python项目&#xff0c;展示如何使用Plotly和ipywidgets构建从基础统计到动态交互的全栈数据可视化方案。 二、核心功能模块 1. 数据生成与预处理 np.random.seed(100)…

Linux进程信号

1.信号的认识 生活中例如闹钟&#xff0c;红绿灯&#xff0c;电话铃声等都属于信号&#xff0c;所白了信号就是中断我们正在做的事情&#xff0c;属于进行事件异步通知机制。 在Linux中信号是发给进程的&#xff0c;信号的产生相较于进程是异步的。 信号的相关知识点&#xff…

Java使用FFmpegFrameGrabber进行视频拆帧,结合Thumbnails压缩图片保存到文件夹

引入依赖 <dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.17</version></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>ja…

c++项目-KV存储-模仿redis实现kv键值对存储的基本功能。

KV存储引擎的技术解析&#xff1a;数组、哈希与红黑树实现及其在网络I/O中的应用。 内容概要&#xff1a;本文档深入介绍了基于数组、哈希表和红黑树的键值存储引擎的设计与实现。文档首先阐述了系统的总体架构与类图关系&#xff0c;之后分别对底层存储结构进行了详细解释&am…

vue3:十一、主页面布局(优化页面跳转方式)

:router"true" 一、参考文章 vue3:十一、主页面布局(实现基本左侧菜单右侧内容效果)-CSDN博客 参考上述文章可知&#xff0c;页面跳转是通过在js中定义的菜单中携带的path&#xff0c;然后通过菜单的点击事件完成的跳转&#xff0c;现在可以进行优化&#xff0c;直…

深入解析 Java Stream API:筛选子节点的优雅实现!!!

&#x1f680; 深入解析 Java Stream API&#xff1a;筛选子节点的优雅实现 &#x1f527; 大家好&#xff01;&#x1f44b; 今天我们来聊聊 Java 8 中一个非常常见的操作&#xff1a;使用 Stream API 从 Map 中筛选出特定条件的元素。&#x1f389; 具体来说&#xff0c;我们…

统计学重要概念:自由度

在统计学中&#xff0c;自由度&#xff08;degrees of freedom&#xff0c;简称df&#xff09;是一个重要的概念&#xff0c;它表示在计算某个统计量时可以自由变化的值的数量。对于一个样本量为n的样本&#xff0c;自由度通常为n-1&#xff0c;这是因为我们需要用样本数据来估…

数据结构-排序

文章目录 1. 排序的概念2. 常见排序算法的实现2.1 插入排序1&#xff09;插入排序一&#xff09;基本思想二&#xff09;特性及时间复杂度三&#xff09;代码实现 2&#xff09;希尔排序&#xff08;缩小增量排序&#xff09;一&#xff09;基本思想二&#xff09;特性及时间复…

压缩壳学习

壳是什么 壳就是软件的一个保护套&#xff0c;防止软件被进行反编译或被轻易地修改。 其作用就是为了保护软件。 常见的大类壳有压缩壳、加密壳、VM 壳的分类。 压缩壳顾名思义就是用来减小软件的文件大小的&#xff1b;加密壳&#xff0c;通过加密软件来保护软件&#xff…

《AI大模型趣味实战》第6集:基于大模型和RSS聚合打造个人新闻电台

《AI大模型趣味实战》第6集&#xff1a;基于大模型和RSS聚合打造个人新闻电台 摘要 本文将带您探索如何结合AI大模型和RSS聚合技术&#xff0c;打造一个功能丰富的个人新闻电台系统。我们将使用Python和PyQt5构建一个桌面应用程序&#xff0c;该应用可以从多个RSS源抓取新闻&…

(学习总结29)Linux 进程概念和进程状态

Linux 进程概念 冯诺依曼体系结构软件运行与存储分级数据流动的理论过程 操作系统操作系统(Operator System) 概念操作系统的功能与作用系统调用和库函数概念 进程概念描述进程 - PCBtask_struct查看进程通过系统调用获取进程标示符 PID通过系统调用 fork 函数创建进程简单使用…

LLM - CentOS上离线部署Ollama+Qwen2.5-coder模型完全指南

文章目录 离线安装OllamaOllama下载Ollama硬件需求Ollama 常用命令参考Ollama安装Ollama 服务管理&开机启动开启局域网访问 Ollama 服务 离线安装模型gguf 文件格式下载Qwen2.5-Coder-7B-Instruct-GGUF格式选择 ( gguf 版本 )构建Modelfile文件加载并运行离线模型测试 集成…

Linux——信号

目录 Linux——信号1.信号的基础了解2.技术应用角度的信号3.产生信号3.1按键组合3.2系统调用产生信号3.2.1 kill()3.2.2 raise()3.2.3 abort() 3.3**.** 软件条件产生信号3.4硬件异常产生信号3.4.1 /0异常3.4.2 内存越界异常 4.理解信号的存在5.总结一下6.核心转储7.全部信号都…

向量叉积的应用——正反画画

1 解题思路 解题思路涉及的向量积相关知识 c实现 #include<iostream> #include<vector>using namespace std;struct TrianglePoint {int x;int y; };int momentForce(TrianglePoint A, TrianglePoint B, TrianglePoint C) {//AB向量&#xff1a;(B.x-A.x, B.y-A.…

构建自定义MCP天气服务器:集成Claude for Desktop与实时天气数据

构建自定义MCP天气服务器:集成Claude for Desktop与实时天气数据 概述 本文将指导开发者构建一个MCP(Model Control Protocol)天气服务器,通过暴露get-alerts和get-forecast工具,为Claude for Desktop等客户端提供实时天气数据支持。该方案解决了传统LLM无法直接获取天气…

Web安全策略CSP详解与实践

引言 &#xff1a;在黑客攻击频发的今天&#xff0c;你的网站是否像“裸奔”一样毫无防护&#xff1f;跨站脚本&#xff08;XSS&#xff09;、数据注入等攻击随时可能让用户数据泄露。今天我们将揭秘一个网站的隐形保镖——内容安全策略&#xff08;CSP&#xff09;&#xff0c…