未加星标

Vue 2.0学习笔记:Vue的transition

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二04 | 时间 2018 | 作者 红领巾 ] 0人收藏点击收藏

动效在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中两者的差异)。先上一张录制的动图:


Vue 2.0学习笔记:Vue的transition

两者的效果就如下图所示这样:


Vue 2.0学习笔记:Vue的transition

如果用代码来描述的话:

/* 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 的话,就自钱的完成了闭合(隐藏)自动过渡到展开(可见)状态。比如下图所示:


Vue 2.0学习笔记:Vue的transition

animation 与 transition 有很大的不同之处,从状态 A 到状态 B 之间有很多中间态,而这些被称为 关键帧 。因此, animation 也常常被称为 帧动画 ,也有人称为 补间动画 。比如下图所示:


Vue 2.0学习笔记:Vue的transition

从上图我们也可以看出来, animation 有很多中间态,即,可以从 A 到 B ,再到 C ,再到 D ,甚至更多。其主要目的是 不断展示某些东西正在改变 。它们可以有结束状态,但与 transition 不同,它们不限于两种状态。比如下面这样的一个示例,它不断地从一种状态变化到另一种状态,但它最终可能会结束。


Vue 2.0学习笔记:Vue的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 2.0学习笔记:Vue的transition
过渡的类名

在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 被删除),在过渡/动画完成之后移除。

用下图来阐述将会更清晰一些:


Vue 2.0学习笔记:Vue的transition

对于这些在过渡中切换的类名来说,如果你使用一个没有使用 name 的 <transition> ,则 v- 是这些类名的默认前缀。如果你使用了 <transition name="fade"> ,那么 v-enter 会替换为 fade-enter ,其他类名也是如此。另外, v-enter-active 和 v-leave-active 可以控制进入/离开过渡的不同的缓和曲线,有关于这部分将在后面会介绍。

结合起来,我们可以用一张图来表示Vue中过渡动效的生命周期,即动效开始、过程、结束对应的类的变化:


Vue 2.0学习笔记:Vue的transition

回到上面的示例中来,在元素 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>

这个时候浏览器会报错:


Vue 2.0学习笔记:Vue的transition

如果我们把另一个 div 的 v-if 用 v-else 来替代:

在Vue中 <transition> 中有多个元素需要有动效效果时,需要使用 <transition-group> 来替代,不然在Vue中则会报错。有关于 <transition-group> 更详细的介绍,我们后续会单独花时间来阐述。另外,在 <transition> 中有相同标签名的元素切换时,需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。即使在技术上没有必要,给在 <transition> 组件中的多个元素设置 key 是一个更好的实践。

现在,你看到的效果可以没有你想像的那么顺滑。这主要是因为,Vue在将第二个元素插入到DOM之前,并不会等第一个元素从DOM中完全删除。所以你看到效果就如上例所示,两个元素之间动效的切换似乎有点闪跳一样。不过我们可以通过 transition 的过渡模式来处理。

过渡模式

上面的示例存在一个问题,先看下图这个效果:


Vue 2.0学习笔记:Vue的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 来实现下面这样的一个圆形菜单效果:


Vue 2.0学习笔记: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 效果,以入如何和第三方库一起结合实现动效。如果感兴趣的话,欢迎持续关注后续的相关更新。

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

代码区博客精选文章
分页:12
转载请注明
本文标题:Vue 2.0学习笔记:Vue的transition
本站链接:https://www.codesec.net/view/620978.html


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(35)