内容简介:动效在Web中一直是一个有争议的问题。动效做得好有助于在你的Web程序上锦上添花,甚至是留住你的用户,也可以具有较好的用户体验;反之,如果动效运用的不好,会给用户带来一种反感,让用户迅速地离开你的应用。怎么提供更友好的动效,并不是今天我们要讨论的重点,我们要讨论的是:在本文中,我们将先重点了解Vue中处理CSS的在具体了解Vue中的
动效在Web中一直是一个有争议的问题。动效做得好有助于在你的Web程序上锦上添花,甚至是留住你的用户,也可以具有较好的用户体验;反之,如果动效运用的不好,会给用户带来一种反感,让用户迅速地离开你的应用。怎么提供更友好的动效,并不是今天我们要讨论的重点,我们要讨论的是: 在Vue应用程序中如何添加动效? 在Vue中,提供了多种方法来给你的运用程序添加动效,比如CSS的 transition
和 animation
动效,以及在Vue的生命周期的钩子函数中操作DOM。甚至你还要以使用第三方动画库,比如 GSAP 或 Velocity.js 来制作动效。
在本文中,我们将先重点了解Vue中处理CSS的 transition
的原理。有了这些知识,就可以开始创建自己的过渡动效。一旦掌握了这些基础知识,就可以快速掌握Vue中的 transition
和 animation
的全部功能。
transition
vs animation
在具体了解Vue中的 transition
之前,咱们先简单的了来了解一下 transition
和 animation
之间的差异(这里所指的是CSS中两者的差异)。先上一张录制的动图:
两者的效果就如下图所示这样:
如果用代码来描述的话:
/* transition*/ .button { background: blue; transition: background; &:hover { background: red; } } /* animation */ @keyframe spin { 0% { color: red; } 50% { color: blue; transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .element { animation: spin 1s ease-in-out 2s infinite; }
也就是说, transition
是指一个元素从 状态 A
到 状态B ,即开始状态是 A
,结束状态是 B
。而其主要的目的是创建一个自然的演示,告诉用户的交互行为已经发生了更改(就是从 A
变成了 B
)。在现实的Web应用中这样的示例也非常的多。比如下拉菜单的效果就是其中的一个典型案例。默认情况下,下拉菜单是收缩闭合的(隐藏不见,就是我们所说的状态 A
),当用户点击了或者鼠标悬浮在菜单项上,下拉菜单就会展开(下拉菜单可见,就是我们所说的状态 B
)。这样的一个过程如果添加了 transition
的话,就自钱的完成了闭合(隐藏)自动过渡到展开(可见)状态。比如下图所示:
animation
与 transition
有很大的不同之处,从状态 A
到状态 B
之间有很多中间态,而这些被称为 关键帧 。因此, animation
也常常被称为 帧动画 ,也有人称为 补间动画 。比如下图所示:
从上图我们也可以看出来, animation
有很多中间态,即,可以从 A
到 B
,再到 C
,再到 D
,甚至更多。其主要目的是 不断展示某些东西正在改变 。它们可以有结束状态,但与 transition
不同,它们不限于两种状态。比如下面这样的一个示例,它不断地从一种状态变化到另一种状态,但它最终可能会结束。
在某种程度上, animation
只是 transition
的一个超级集合,因为它添加了更多的中间状态。虽然 transition
只是从状态 A
到状态 B,但
animation 可以根据需要拥有任意多的中间状态。也就是说,只要理解了
transition 的基本原理之后,在去理解
animation 就不是什么一件难事了。这也就是我们今天为什么把重点放在
transition`上。
transition元素
在Vue中有一个 <transition>
元素(即一个容器),它主要用来处理元素或组件上的 transition
动效,CSS和JavaScript的 animation
动效,而且会让你处理这些动效变得简地多。而在CSS的 transition
动效中, <transition>
元素主要负责应用和取消类(元素的类名)。而你所要做的就是定义元素在 transition
动效期间元素的样式。
<transition>
在Vue中使用非常的简单,把要带动效的元素放到这个容器之中,同时使用 name
给其一个名称,比如 fade
:
<transition name="fade"> <h1 v-if="show">Hello! W3cplus.com (^_^)</h1> </transtion>
当在 <transition>
容器中的元素在显示(插入)或隐藏(删除)时,Vue会自动嗅探到目标元素是否应用了CSS的 transition
或 animation
,如果是,在恰当的时机添加或删除CSS类名。
简单地说:
<transition>
是Vue已经封装好的一个组件,可以给任何元素和组件添加进入或离开过渡效果。
在Vue中的下面这几种情形会产生相应的过渡或动画效果:
v-if v-show
比如下面这个示例:
<!-- FadeText --> <template> <div class="wrapper"> <transition name="fade"> <h1 v-if="isShow">{{ msg }}</h1> </transition> <button @click="isToggle" :class="isShow ? 'is-show' : 'is-hidden'"> {{ isShow ? "隐藏" : "显示" }} </button> </div> </template> <script> export default { name: "FadeText", data() { return { isShow: true, msg: "Hello! W3cplus.com (^_^)" }; }, methods: { isToggle() { this.isShow = !this.isShow; } } }; </script> <style scoped> .fade-enter-active, .fade-leave-active { transition: opacity 0.5s; } .fade-enter, .fade-leave-to { opacity: 0; } </style>
效果如下:
上面这个简单的过渡效果使用的是CSS的 transition
方式来实现。那么 v-if
在切换元素 h1
的时候发生了什么呢?
- 当
v-if
绑定的值isShow
在true
和false
之间切换的时候,<transition>
中的元素<h1>
会插入和删除之间进行切换 - 自动嗅探目标元素
h1
是否应用了CSS的transition
或animation
。如果是,则会在元素插入时添加CSS类名,并判断动画加载完之后删除CSS类名 - 如果过渡组件提供了 JavaScript钩子函数 (这部分后面会介绍),这些钩子函数在恰当的时机被调用。在这个示例中并没有用到JavaScript钩子函数,所以不会被执行
- 如果没有找到JavaScript钩子并且也没有检测到CSS的
transition
或animation
,DOM操作(插入或删除)在下帧中立即执行。( 注意:此指浏览器逐帧动画机制,和 Vue 的nextTick
概念不同 )
这个时候,通过浏览器的动画( Animations )选项可以看到动效的整个过程,如下图所示:
过渡的类名
在Vue中使用 <transition>
制作过渡效果时,可以给过渡元素添加类名,在Vue中有六个类名,可以使用它们分别处理处理元素插入和删除时过渡效果。其中三个类用于处理元素插入时状态 A
到状态 B
过渡,另外三个类用于处理元素删除时状态 A
到状态 B
的过渡。
在插入或显示组件时发生 enter
过渡,对应的类名是 v-enter
、 v-enter-active
和 v-enter-to
;在隐藏或删除组件时发生 leave
过渡,对应的类名是 v-leave
、 v-leave-active
和 v-leave-to
。每个类对应的作用如下:
-
v-enter
:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。 -
v-enter-active
:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。 -
v-enter-to
: 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时v-enter
被移除),在过渡/动画完成之后移除。 -
v-leave
: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。 -
v-leave-active
:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。 -
v-leave-to
: 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时v-leave
被删除),在过渡/动画完成之后移除。
用下图来阐述将会更清晰一些:
对于这些在过渡中切换的类名来说,如果你使用一个没有使用 name
的 <transition>
,则 v-
是这些类名的默认前缀。如果你使用了 <transition name="fade">
,那么 v-enter
会替换为 fade-enter
,其他类名也是如此。另外, v-enter-active
和 v-leave-active
可以控制进入/离开过渡的不同的缓和曲线,有关于这部分将在后面会介绍。
结合起来,我们可以用一张图来表示Vue中过渡动效的生命周期,即动效开始、过程、结束对应的类的变化:
回到上面的示例中来,在元素 h1
加载到DOM之前, h1
会添加 fade-enter
类名,对应的动效也就被添加到该元素中,只对应一帧。因此,在DOM渲染时,将动画的 opacity:0
应用到 h1
元素上,此时该元素也就隐藏不可见。在动效的整个过程中, fade-enter-active
类也被添加到该元素中,在该示例中,动画被设置为 .5s
。 fade-leave
和 fade-leave-active
也以相同的方式运用于 h1
元素上。
在示例中,并没有显式的在 fade-leave
类中设置 opacity: 1
,那是因为 opacity
的默认值已经是 1
。这也就是为什么在 fade-enter-active
结束时 opacity
也不显式设置为 1
的原因。
在Vue中,如果元素放置到 <transition>
中,Vue会自动检测元素上的 v-if
指令。比如上面的示例,如果 isShow
的值为 true
,那么 h1
会渲染显示,当你点击按钮时,会自动切换 isShow
的值。从而也控制了 h1
元素的显示或隐藏(插入或删除)。
这里需要注意的一点是, Vue只能对 <transition>
中的一个元素进行动效处理。相反,在任何给定的实例中,只能将 <transition>
中的一个元素插入到DOM中 。比如下同这个示例,在Vue中无法正常的工作:
<!-- ToggleAlert.vue --> <template> <div class="toogle-alert"> <button @click="isToggle" :class="isShow ? 'is-show' : 'is-hidden'"> {{ isShow ? "隐藏" : "显示" }} </button> <transition name="fade"> <div class="alert alert-info" v-if="isShow" key="info">{{ alertInfoMsg }}</div> <div class="alert alert-error" v-if="isShow" key="error">{{ alertErrorMsg }}</div> </transition> </div> </template> <script> export default { name: "ToggleAlert", data() { return { isShow: true, alertInfoMsg: "Hello! W3cplus.com!", alertErrorMsg: "Goodbye! W3cplus.com!" }; }, methods: { isToggle() { this.isShow = !this.isShow; } } }; </script> <style scoped> .fade-enter, .fade-leave-to { opacity: 0; } .fade-enter-active, .fade-leave-activ { transition: opacity 0.5s cubic-bezier(1, 0.5, 0.8, 1); } </style>
这个时候浏览器会报错:
如果我们把另一个 div
的 v-if
用 v-else
来替代:
在Vue中 <transition>
中有多个元素需要有动效效果时,需要使用 <transition-group>
来替代,不然在Vue中则会报错。有关于 <transition-group>
更详细的介绍,我们后续会单独花时间来阐述。另外,在 <transition>
中有相同标签名的元素切换时,需要通过 key
特性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。即使在技术上没有必要,给在 <transition>
组件中的多个元素设置 key
是一个更好的实践。
现在,你看到的效果可以没有你想像的那么顺滑。这主要是因为,Vue在将第二个元素插入到DOM之前,并不会等第一个元素从DOM中完全删除。所以你看到效果就如上例所示,两个元素之间动效的切换似乎有点闪跳一样。不过我们可以通过 transition
的过渡模式来处理。
过渡模式
上面的示例存在一个问题,先看下图这个效果:
div.alert-info
和 div.alert-error
两个元素都被重绘了,一个离开过渡的时候另一个开始进入过渡。其实这也是 <transition>
的默认行为,即 进入和离开同时发生 。
在Vue中提供了两种过渡模式来解决上述问题:
-
in-out
:新元素先进行过渡,完成之后当前元素过渡离开 -
out-in
:当前元素先进行过渡,完成之后新元素过渡进入
这样我们就可以使用 out-in
重写上面的示例:
<transition name="fade" mode="out-in"> <div class="alert alert-info" v-if="isShow" key="info"> {{ alertInfoMsg }} </div> <div class="alert alert-error" v-else="!isShow" key="error"> {{ alertErrorMsg }} </div> </transition>
效果如下:
设置初始渲染的过渡
在Vue中,可以通过 appear
特性设置节点在初始渲染的过渡。
<transition name="fade" mode="out-in" appear> <div class="alert alert-info" v-if="isShow" key="info"> {{ alertInfoMsg }} </div> <div class="alert alert-error" v-else="!isShow" key="error"> {{ alertErrorMsg }} </div> </transition>
这里默认和进入和离开过渡一样,同样也可以自定义 CSS 类名:
<transition appear appear-class="custom-appear-class" appear-to-class="custom-appear-to-class" appear-active-class="custom-appear-active-class" > <!-- ... --> </transition>
同样可以对应的类名添加样式:
.custom-appear-class { opacity: 0; transform: translateX(100%); } .custom-appear-active-class { transition: 2s; }
比如上面的示例,按照上面的代码进行调整之后,可以发看到第一个 .alert
插入到DOM中时,整个 .alert
会从右侧移入进来,效果如下:
示例: 使用transition制作一个圆形菜单
通过上面的学习,我们接下来使用Vue的 transition
来实现下面这样的一个圆形菜单效果:
这个案例其实非常的简单,通过一个 <transition>
来触发多个子元素的过渡效果,我们只需要定义元素对应的过渡效果即可,而其他的事情都将交给Vue来搞定。
<transition name="move" mode="out-in" appear> <ul class="menu" v-show="isShow"> <li v-for="(item, index) in menus" :key="index" class="menuitem-wrapper" > <div class="icon-holder"> <a href="#" class="menu-item"> <i class="material-icons">{{ item }}</i> </a> </div> </li> </ul> </transition>
只需要在对应的 transition
类中控制 transform
的样式:
.move-enter-active, .move-leave-active { transition: all 0.08s ease-in-out; } .move-enter, .move-leave-to { transform: scale(0); }
最终效果如下:
总结
这篇文章主要介绍了Vue中如何使用 <transition>
来实现 transition
动效。这只是Vue中制作动效的最基础部分,但这些基础部分是帮助我们实现更为复杂的动效的基础。在接下来中我们将再一起探讨如何在Vue中实现CSS的 animation
效果,以入如何和第三方库一起结合实现动效。如果感兴趣的话,欢迎持续关注后续的相关更新。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 【每日笔记】【Go学习笔记】2019-01-04 Codis笔记
- 【每日笔记】【Go学习笔记】2019-01-02 Codis笔记
- 【每日笔记】【Go学习笔记】2019-01-07 Codis笔记
- Golang学习笔记-调度器学习
- Vue学习笔记(二)------axios学习
- 算法/NLP/深度学习/机器学习面试笔记
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
REST实战
Jim Webber、Savas Parastatidis、Ian Robinson / 李锟、俞黎敏、马钧、崔毅 / 东南大学出版社 / 2011-10 / 78.00元
为何典型的企业项目无法像你为web所开发的项目那样运行得如此平滑?对于建造分布式和企业级的应用来说,rest架构风格真的提供了一个可行的替代选择吗? 在这本富有洞察力的书中,三位soa专家对于rest进行了讲求实际的解释,并且通过将web的指导原理应用到普通的企业计算问题中,向你展示了如何开发简单的、优雅的分布式超媒体系统。你将会学习到很多技术,并且随着一家典型的公司从最初的小企业逐渐成长为......一起来看看 《REST实战》 这本书的介绍吧!