玩转 Vue 3 全家桶
大圣
前百度前端架构师
38321 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 44 讲
玩转 Vue 3 全家桶
15
15
1.0x
00:00/00:00
登录|注册

09 | 动画:Vue中如何实现动画效果?

实现振动效果的方法讨论
使用transition组件控制动画元素进入和离开
使用JavaScript实现复杂动画效果
页面切换动画的实现方式
使用transition-group实现列表动画
使用transition包裹元素实现动效
使用transition组件控制组件动画
使用animation和keyframe组合实现动画
使用CSS属性transition实现过渡效果
transition属性控制元素宽度变化
思考题
JavaScript动画
Vue 3动画入门
前端过渡和动效
动画效果实现

该思维导图由 AI 生成,仅供参考

你好,我是大圣。
在上一讲中,我给你讲解了组件化设计的思路,有了组件,我们就可以积木式地搭建网页了。领会组件设计的思路后,小圣继续丰富了清单组件的功能,在组件的功能实现完毕后,我给他提出了一个新的要求,希望能有一些动画效果的加入,让这个应用显得不再这么生硬。
小圣自己琢磨以后,又找过来咨询我 Vue 3 中实现动画的方式,所以今天我就来跟你聊一下 Vue 中应该如何实现常见的过渡和动效。在讲解过程中,我们会继续给之前那个清单应用添砖加瓦,给它添加更多酷炫的玩法,让我们正式开始今天的学习吧。

前端过渡和动效

在讲 Vue 中的动效和过渡之前,我想先跟你聊一下前端的过渡和动效的实现方式。举个例子,假设我现在有这样一个需求:在页面上要有一个 div 标签,以及一个按钮,点击页面的按钮后,能够让 div 标签的宽度得到增加。
在下面的代码中,我们可以实现上面所说的这个效果。这段代码里,首先是一个 div 标签,我们使用 width 控制宽度。我们想要的前端效果是,每次点击按钮的时候,div 标签的宽度都增加 100px。
<template>
<div class="box" :style="{width:width+'px'}"></div>
<button @click="change">click</button>
</template>
<script setup>
import {ref} from 'vue'
let width= ref(100)
function change(){
width.value += 100
}
</script>
<style>
.box{
background:red;
height:100px;
}
</style>
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Vue 中实现动画效果的方法和实践是本文的重点内容。文章首先介绍了使用 CSS 属性 transition 和 animation 实现元素属性的缓慢变化和动画效果的方法。接着详细介绍了在 Vue 3 中使用内置的 transition 组件来控制组件的动画,并给出了一个简单的例子。然后,通过优化清单应用的交互场景,展示了如何在 Vue 中使用 transition 包裹元素,并设置相应的 CSS 过渡效果,实现了弹窗的动画效果。此外,还介绍了使用 transition-group 实现列表元素的动画和在 vue-router 中实现页面切换动画的方法。最后,通过引入 JavaScript 实现更复杂的动画效果,如购物车中商品飞入的效果。总结指出,动画的设计需要系统地设计效果,不宜过多,而实现更复杂的动画效果需要借助 JavaScript 和第三方库的支持。整体而言,本文通过实际案例和代码示例生动地展示了在 Vue 中实现动画效果的方法和实践。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《玩转 Vue 3 全家桶》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(39)

  • 最新
  • 精选
  • ll
    边看回顾学过和用过的动画知识,总结下: 1. 为什么要用动画? 首先肯定不是为了“炫技”,从产品的角度,个人觉得是为了“降低用户理解难度”,因为 “动” 意味着有“生气”,比较“自然”。回想下日常生活中,碰到的人或事,如果比较“自 然”是不是意味着比较“好搞”,比较“容易相处”。而我们用动画就是为了实现这样的效果。 当然用户体验这种事,大公司应该专门有个UX部门,我们前端主要还是要以实现为主, 工程师还是要“多、快、好、省”的把事情做成,这就涉及到动画的具体实现。 2. 动画的实现 个人觉得动画的实现就是CSS的事,JS实现动画也是动态改变某个元素的CSS属性。这个 过程可以看下隔壁李兵老师的《浏览器工作原理与实践》其中的渲染流水线的论述,这 里强调下,如果较关注的动画性能问题,还是从动画的本质理解起: 动画的本质:“从哪里来,到哪里去,中间过程是怎么样的”。 以本节第一段代码来说,从哪里来"from",就是 box.width=100px;去哪"to", 就是 box.width += 100px;后面为了“动起来”,加了个中间过程,是用"transition"实现的, 当然还有其他实现,深究还涉及到贝叶斯曲线函数,“弹簧函数”之类的技术实现。 提下动画的性能问题,简单说就是,改变有些 CSS 属性会影响渲染流程,就是常说的 “重排,重绘,合成”。提供两个资源,可以具体看下,改变哪些属性会触发。 – https://csstriggers.com/ – https://gist.github.com/paulirish/5d52fb081b3570c81e3a 3. Vue 组件化实现 Vue 提供了<transition>, <transition-group>两个组件来帮助我们实现业务中的动画 需求,大大的提高了我们的开发效率。 很神奇,有需求的同学可以看看源码,看看怎么实现的,应该能学到不少知识。

    作者回复: 太用心啦!

    2021-11-05
    6
    60
  • 我叫兽儿…
    动手实现清单删除动画的时候,踩了一个小坑,在此记录一下,代码如下: <ul v-if="todolist.length"> <transition-group name="list" tag="ul"> <li v-for="(item, index) in todolist" :key="index"> <input type="checkbox" v-model="item.checked" /> <span>{{ item.title }}</span> <span @click="deleteItem($event, index)" class="delete">x</span> </li> </transition-group> </ul> 这里for循环我使用了index作为key,导致删除某一个li时,动画总是作用到最后一个li上。看了半天发现index会随着li的删除而变化,比如:我删除了第三个li,但是第四个会立马补上变成第三个,后面的li会依次向前补位,导致动画错乱。解决方式就是使用唯一的不会变的值作为key,比如id. 愿共同学习,共同进步!

    作者回复: 很棒的总结和体验 第一部分实战代码在这里呀,欢迎遇见bug了提pr呀 https://github.com/shengxinjing/geektime-vue-course

    2021-11-07
    3
    18
  • Justin
    想請問一下 function enter(el,done){ document.body.offsetHeight el.style.transform = `translate(0,0)` el.addEventListener('transitionend', done) } document.body.offsetHeight 這一行的作用是什麼? 感謝

    作者回复: 手动触发一次重绘,开始动画

    2021-11-05
    5
    11
  • Geek_0c8aff
    // bug, 删除todo的最后一项,加入垃圾桶的动画位置不对(0,0),以下是我的修改。 function removeTodo(e: any, i: number) { animate.el = e.target animate.show = true setTimeout(()=>{ todos.value.splice(i, 1) },100) }

    作者回复: 赞,nextTick也可以

    2021-11-21
    5
    8
  • 柒月
    页面切换动画的时候,要求路由组件必须要有个根元素包裹,不然动画不生效的。 https://stackoverflow.com/questions/65553121/vue-3-transition-renders-non-element-root-node-that-cannot-be-animated

    作者回复: 很赞的提醒,第一部分实战代码在这里呀,欢迎遇见bug了提pr呀 https://github.com/shengxinjing/geektime-vue-course

    2021-11-09
    7
    8
  • 雪狼
    课程非常棒,在学习过程中提几个建议 1、部分代码能加点注释更方便理解,比如enter函数 2、css没有写全,比如垃圾筐的,这倒也不是大问题 3、如果每讲,最后能有一个本讲完整的实例代码贴到最后,更方便查看 4、动画需要一个root节点包裹才能生效,课程中没有体现出来的

    作者回复: 感谢建议,我尽快改进

    2021-12-20
    6
  • bugu
    问一个问题:列表动画那一部分transition-group ,设置 tag 的作用是什么呢?我尝试去掉tag,没有看出什么差异。 还有下面move的动画设定 .flip-list-move { transition: transform 2s ease; } 我尝试修改和删除,也没有看出什么差异。 请帮忙指定一下,谢谢老师和各位同学

    作者回复: tag的目的是给li渲染一个ul父元素,倒是不会影响实际功能,不过会让html更语义化一些

    2021-11-05
    5
    6
  • Zachy
    // 强迫症下把删除动画精准还原到垃圾桶位置,暂时没加抛物线,否则效果更佳。 const {animate,beforeEnter, enter, afterEnter,removeTodo} = useAnimation(); function useAnimation(){ let animate = reactive({ show: false, el: null, }); const dustbin ={ el:null, pos:[], init(queryStr){ this.el = document.querySelector(queryStr); this.getPos(); }, getPos(){ const { left, top} = this.el.getBoundingClientRect(); this.pos[0] = left; this.pos[1] = top; } } function beforeEnter(el) { let dom = animate.el; let rect = dom.getBoundingClientRect(); const aniEl= document.querySelector('.animate'); //动画元素 调整到dustbin的位置,也可以css直接写精准位置 aniEl.style.left = `${dustbin.pos[0]}px`; aniEl.style.top= `${dustbin.pos[1]}px`; //计算并赋值偏移量 let dx = dustbin.pos[0] - rect.left; let dy = dustbin.pos[1] - rect.top; el.style.transform = `translate(-${dx}px, ${dy*-1}px)`; } function enter(el, done) { document.body.offsetHeight; el.style.transform = `translate(0,0)`; el.addEventListener("transitionend", done); } function afterEnter(el) { animate.show = false; el.style.display = "none"; } function removeTodo(e,i){ animate.el = e.target animate.show = true todos.value.splice(i, 1); dustbin.init('.dustbin'); } return {animate,beforeEnter,enter,afterEnter,removeTodo} }

    作者回复: very geliable!!!

    2021-11-28
    2
    5
  • 微妙
    el.style.transform = `translate(-${x}px, ${y}px)` 模板字符串中当x为负数时会被识别为 --xpx,导致transform识别不出而变为 translate(0px, 0px); 应先计算好x、y的值,然后在模板字符串内赋值

    作者回复: 给你点个赞,这里演示我确实没考虑到负数的情况,囧 第一部分实战代码在这里呀,欢迎遇见bug了提pr呀 https://github.com/shengxinjing/geektime-vue-course

    2021-11-08
    4
  • Geek_1ecc87
    为什么要在v-for li中指定key添加任务的时候动画才会生效?

    作者回复: key是vue内部识别一个dom是否可以重用的标志 没有key的话dom很难复用

    2022-01-14
    2
    3
收起评论
显示
设置
留言
39
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部