Vue从基础到进阶教程之动画效果

过渡效果在交互体验中的重要性不言而喻。以往我们使用jQuery添加或移除元素的类,搭配CSS中定义好的样式,再引用一些JavaScript库之后,可以做出非常复杂、惊艳的动态效果,不过这一套方法仍略显烦琐。Vue.js内置了一套过渡系统,可以在元素从 DOM中插入或移除时自动应用过渡效果。Vue.,js会在适当的时机触发CSS 过渡或动画,用户也可以提供相应的JavaScript钩子函数在过渡过程中执行自定义DOM操作。

过渡效果就是在DOM元素进行切换、隐藏、插入和移除的时候加入一些酷炫的效果,使得过渡更加自然和美观,那么要想让组件实现动画,最基础的做法就是:

应用过渡效果,在需要加动画的地方,加入transition标签。代码示例如下:

transition特性可以与以下资源一起搭配使用:

  • v-if
  • v-show
  • v-for(v-for(只在插入和删除时触发,使用vue-animated-list插件)
  • 动态组件(见“组件”一章)

我们先来看个简单基础的动画案例,大家看案例代码:

例8-1 Demo0801.html

程序的运行结果如下:

图 8- 1 入门案例

点击切换按钮,我们看到div框有一个淡入淡出的效果,原理如下:

当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理:

  1. 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。
  2. 如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。
  3. 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。

在案例中我们使用到了一些过渡的类名,现在来看看,在元素在进入/离开的过渡中,会有 6 个 class 切换。

  1. v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
  2. v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。
  3. v-enter-to:2.1.8 版及以上定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。
  4. v-leave:定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。
  5. v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。
  6. v-leave-to:2.1.8 版及以上定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

图 8- 2 过渡类名

特别说明,对于这些在过渡中切换的类名来说,如果你使用一个没有名字的 <transition>,则 v- 是这些类名的默认前缀。如果你使用了 <transition name=\”my-transition\”>,那么 v-enter 会替换为 my-transition-enter。

我们常用的过渡都是使用 CSS 的样式规则实现过渡,借助css的样式实现酷炫的过渡效果。

我们来看8-2案例代码:

例8-2 Demo0802.html

程序的运行结果跟例子8-1的区别是在水平位置上的偏移实现了平滑的过渡。我们可以借鉴之前学习的transform属性,灵活使用,还可以加入更多的样式规则,实现想要的效果。

在这我们需要注意,入场类名有三个:

<name>-enter:入场前

<name>-enter-active:入场持续的过程

<name>-enter-to:入场的结束

出场类名有三个:

<name>-leave:出场前

<name>-leave-active:出场持续的过程

<name>-leave-to:出场的结束

在上一小节中,我们初步了解了Vue使用transition标签实现过渡的效果,接下来我们来看看具体的实现过程,以及原理。

首先,我们来看以下代码:

上面的代码我们只定义了进入前的类,以及进入的持续过程,我们通过过程看原理:

当动画执行的一瞬间,会在内部的div上增加两个class名字,分别是fade-enter和fade-enter-active,之所以是fade-开头,是因为transiton标签name是fade。当动画运行到第二帧的时候,Vue又会帮助你把fade-enter删除,然后添加一个fade-enter-to,再当动画执行到结束的一瞬间,又把fade-enter-active和fade-enter-to删除掉。

注意,在第一帧的时候,fade-enter-active和fade-enter同时存在,并且opacity=0,在第二帧的时候,fade-enter被删除,opacity恢复到原来的初始状态,就是1,在这个过程中,opacity发生了变化,所以fade-enter-active就让这个变化在3秒内完成,完成后进入到fade-enter-to的状态,但是我们没有定义则默认就是过程持续后的状态,opacity为1,此时进入的过渡状态已经完成,删除fade-enter-to和fade-enter-active,这就是元素进入的一个完整的过程。

但是如果要加入fade-enter-to,需要注意下图所示:

如果初始定义中没有加宽和高,则进入动画完成后,该div就会消失,所以最好在这定义好div的样式规则

width height

如果想要某个样式规则在过渡中有效果,就必须写在<name>-enter中也加入,不能只在#app div的初步定义中写,否则在接下来的active和enter-to中则无效。

以上讲解入场的过程原理,接下来看出场的过程原理:

加入以下代码:

我们发现,进入效果完成后,我们定义了离开过渡的开始状态fade-leave,在data中show的值为false时,开始离开,此时会为类加上fade-leave和fade-leave-active状态,离开的持续过程完成后,进入结束状态fade-leave-to,此时fade-leave已经被删除,出场完成后,fade-leave-active和fade-leave-to被删除。

整个过程总结如下:

【v-enter】

定义进入过渡的开始状态。在元素被插入时生效,在下一个帧移除

【v-enter-active】

定义过渡的状态。在元素整个过渡过程中作用,在元素被插入时生效,在 transition 或 animation 完成之后移除。 这个类可以被用来定义过渡的过程时间,延迟和曲线函数

【v-enter-to】

定义进入过渡的结束状态。在元素被插入一帧后生效(与此同时 v-enter 被删除),在 transition 或 animation 完成之后移除

【v-leave】

定义离开过渡的开始状态。在离开过渡被触发时生效,在下一个帧移除

【v-leave-active】

定义过渡的状态。在元素整个过渡过程中作用,在离开过渡被触发后立即生效,在 transition 或 animation 完成之后移除。 这个类可以被用来定义过渡的过程时间,延迟和曲线函数

【v-leave-to】

定义离开过渡的结束状态。在离开过渡被触发一帧后生效(与此同时 v-leave 被删除),在 transition 或 animation 完成之后移除

以上就是我们整个过渡的过程和原理,接下来我们来看动画。

上一小节,我们实现了CSS过渡,通常过渡使用的是transition,本节课我们使用animation来加入动画效果。

例8-3 Demo0803.html

  1. <!DOCTYPE html>
  2. <html lang=\”en\”>
  3. <head>
  4. <meta charset=\”UTF-8\”>
  5. <meta http-equiv=\”X-UA-Compatible\” content=\”IE=edge\”>
  6. <meta name=\”viewport\” content=\”width=device-width, initial-scale=1.0\”>
  7. <title>动画</title>
  8. <!– 在线引入vue.js,必须引入否则无法使用vue–>
  9. <script src=\”https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js\”></script>
  10. <style>
  11. #app {
  12. text-align: center;
  13. }
  14. #app div {
  15. margin: 30px auto;
  16. background-color: bisque;
  17. width: 200px;
  18. height: 200px;
  19. border-radius: 50%;
  20. }
  21. .fade-enter-active {
  22. animation: ani .5s;
  23. }
  24. .fade-leave-active {
  25. animation: ani .5s reverse;
  26. }
  27. @keyframes ani {
  28. 0% {
  29. transform: scale(0);
  30. }
  31. 50% {
  32. transform: scale(1.5);
  33. }
  34. 100% {
  35. transform: scale(1);
  36. }
  37. }
  38. </style>
  39. </head>
  40. <body>
  41. <div id=\”app\”>
  42. <button @click=\”show = !show\”>显示/隐藏</button>
  43. <br>
  44. <transition name=\”fade\”>
  45. <div v-if=\”show\”></div>
  46. </transition>
  47. </div>
  48. </body>
  49. <script>
  50. let vm = new Vue({
  51. el: \’#app\’,
  52. data: {
  53. show: false
  54. },
  55. })
  56. </script>
  57. </html>

图 8- 4 显示效果

例8-3中我们使用了animation给div进入和离开分别设置了缩放的动画效果,也可以借助之前学习的animation的知识实现更多酷炫的效果。

Vue 为了知道过渡的完成,必须设置相应的事件监听器。它可以是 transitionend 或 animationend ,这取决于给元素应用的 CSS 规则。如果使用其中任何一种,Vue 能自动识别类型并设置监听。

但是,在一些场景中,需要给同一个元素同时设置两种过渡动效,比如 animation 很快的被触发并完成了,而 transition 效果还没结束。在这种情况中,就需要使用 type 特性并设置 animation 或 transition 来明确声明需要 Vue 监听的类型,我们来看下面的案例:

例8-4 Demo0804.html

  1. <!DOCTYPE html>
  2. <html lang=\”en\”>
  3. <head>
  4. <meta charset=\”UTF-8\”>
  5. <meta http-equiv=\”X-UA-Compatible\” content=\”IE=edge\”>
  6. <meta name=\”viewport\” content=\”width=device-width, initial-scale=1.0\”>
  7. <title>动画</title>
  8. <!– 在线引入vue.js,必须引入否则无法使用vue–>
  9. <script src=\”https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js\”></script>
  10. <style>
  11. #app {
  12. text-align: center;
  13. }
  14. #app div {
  15. margin: 30px auto;
  16. background-color: bisque;
  17. width: 200px;
  18. height: 200px;
  19. border-radius: 50%;
  20. }
  21. .fade-enter,
  22. .fade-leave-to {
  23. opacity: 0;
  24. }
  25. .fade-enter-active,
  26. .fade-leave-active {
  27. transition: opacity 1s;
  28. animation: bounce-in 5s;
  29. }
  30. @keyframes bounce-in {
  31. 0% {
  32. transform: scale(0);
  33. }
  34. 50% {
  35. transform: scale(1.5);
  36. }
  37. 100% {
  38. transform: scale(1);
  39. }
  40. }
  41. </style>
  42. </head>
  43. <body>
  44. <div id=\”app\”>
  45. <button @click=\”show = !show\”>显示/隐藏</button>
  46. <br>
  47. <transition name=\”fade\” type=\”transition\”>
  48. <div v-if=\”show\”></div>
  49. </transition>
  50. </div>
  51. </body>
  52. <script>
  53. let vm = new Vue({
  54. el: \’#app\’,
  55. data: {
  56. show: false
  57. },
  58. })
  59. </script>
  60. </html>

通过以上案例,我们发现如何设置type=‘transition’则主要是监听过渡为主,动画则不会执行1.5倍的缩放,因为过渡1s就完成了。如果type=’animation’则以监听动画为主,就会完整的执行动画,这一点大家在混合使用的时候注意。

我们可以通过以下 attribute 来自定义过渡类名:

  • enter-class
  • enter-active-class
  • enter-to-class (2.1.8+)
  • leave-class
  • leave-active-class
  • leave-to-class (2.1.8+)

他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css 结合使用十分有用。

使用animate的步骤:

第一步:下载

https://daneden.github.io/animate.css

第二步:引入

在线引入:

<link href=\”https://cdn.jsdelivr.net/npm/animate.css@3.5.1\” rel=\”stylesheet\” type=\”text/css\”>

本地引入:

<link href=\”./animate.min.css\” rel=\”stylesheet\” type=\”text/css\”/>

例8-5 Demo0805.html

  1. <!DOCTYPE html>
  2. <html lang=\”en\”>
  3. <head>
  4. <meta charset=\”UTF-8\”>
  5. <meta http-equiv=\”X-UA-Compatible\” content=\”IE=edge\”>
  6. <meta name=\”viewport\” content=\”width=device-width, initial-scale=1.0\”>
  7. <title>动画</title>
  8. <!– 在线引入vue.js,必须引入否则无法使用vue–>
  9. <script src=\”https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js\”></script>
  10. <link href=\”https://cdn.jsdelivr.net/npm/animate.css@3.5.1\” rel=\”stylesheet\” type=\”text/css\”>
  11. <style>
  12. #app {
  13. text-align: center;
  14. }
  15. #app div {
  16. margin: 30px auto;
  17. background-color: bisque;
  18. width: 200px;
  19. height: 200px;
  20. border-radius: 50%;
  21. }
  22. .fade-enter,
  23. .fade-leave-to {
  24. opacity: 0;
  25. }
  26. .fade-enter-active,
  27. .fade-leave-active {
  28. transition: opacity 1s;
  29. animation: bounce-in 5s;
  30. }
  31. @keyframes bounce-in {
  32. 0% {
  33. transform: scale(0);
  34. }
  35. 50% {
  36. transform: scale(1.5);
  37. }
  38. 100% {
  39. transform: scale(1);
  40. }
  41. }
  42. </style>
  43. </head>
  44. <body>
  45. <div id=\”app\”>
  46. <button @click=\”show = !show\”>显示/隐藏</button>
  47. <br>
  48. <transition name=\”fade\” enter-active-class=\”animated tada\” leave-active-class=\”animated bounceOutRight\”>
  49. <div v-if=\”show\”></div>
  50. </transition>
  51. </div>
  52. </body>
  53. <script>
  54. let vm = new Vue({
  55. el: \’#app\’,
  56. data: {
  57. show: false
  58. },
  59. })
  60. </script>
  61. </html>

至此,便可以实现vue+animate.css动画库的结合使用。它的优势,像某些比较复杂的动画效果,此时便省去手写过程,直接引入使用现有动画库即可,大大提高了开发效率。

注意:

1、必须使用transition标签的自定义动画名属性,即enter-active-class和leave-active-class;

2、使用时必须加入animated类名。

如果想在页面初始化时渲染动画效果,此时需要用到appear呈现属性和appear-active-class呈现过渡属性,语法如下:

<transition appear>

<!– … –>

</transition>

如果只写appear,则初始化动画默认和进入/离开过渡效果一样,同样也可以自定义 CSS 类名。

<transition

appear

appear-class=\”custom-appear-class\”

appear-to-class=\”custom-appear-to-class\” (2.1.8+)

appear-active-class=\”custom-appear-active-class\”

>

<!– … –>

</transition>

但是要注意,它只是在第一次渲染的时候才会起作用。

例8-6 Demo0806.html

  1. <!DOCTYPE html>
  2. <html lang=\”en\”>
  3. <head>
  4. <meta charset=\”UTF-8\”>
  5. <meta http-equiv=\”X-UA-Compatible\” content=\”IE=edge\”>
  6. <meta name=\”viewport\” content=\”width=device-width, initial-scale=1.0\”>
  7. <title>动画</title>
  8. <!– 在线引入vue.js,必须引入否则无法使用vue–>
  9. <script src=\”https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js\”></script>
  10. <link href=\”https://cdn.jsdelivr.net/npm/animate.css@3.5.1\” rel=\”stylesheet\” type=\”text/css\”>
  11. <style>
  12. #app div {
  13. width: 200px;
  14. height: 200px;
  15. background-color: antiquewhite;
  16. }
  17. .fade-enter,
  18. .fade-leave-to {
  19. opacity: 0;
  20. }
  21. .fade-enter-active,
  22. .fade-leave-active {
  23. transition: opacity 3s;
  24. }
  25. </style>
  26. </head>
  27. <body>
  28. <div id=\”app\”>
  29. <transition name=\”fade\” enter-active-class=\”animated swing fade-enter-active\”
  30. leave-active-class=\”animated swing fade-leave-active\”>
  31. <div v-show=\”show\”>
  32. 我是要显示的内容
  33. </div>
  34. </transition>
  35. <button @click=\”show=!show\”>点击</button>
  36. </div>
  37. </body>
  38. <script>
  39. var count = 0;
  40. new Vue({
  41. el: \’#app\’,
  42. data: {
  43. show: true
  44. },
  45. methods: {
  46. }
  47. })
  48. </script>
  49. </html>

例8-6中,在页面初始化时候是没有动画效果的,点击按钮的时候才会触发动画;如果想要在页面初始化就有动画效果,就必须加appear,也可以指定初始化动画,如下示例:

<div id=\”app\”>

<transition appear appear-class=\”animated shakeY\” appear-to-class=\”animated wobble\”

appear-active-class=\”animated jello\” name=\”fade\” enter-active-class=\”animated swing fade-enter-active\”

leave-active-class=\”animated swing fade-leave-active\”>

<div v-show=\”show\”>

我是要显示的内容

</div>

</transition>

<button @click=\”show=!show\”>点击</button>

</div>

但是这里有一些问题:关于appear-class、 appear-to-class、 appear-active-class的相同属性那个起作用的问题。

四种情况:(与他们在style中的排列顺序有关系)

1、appear-class、 appear-to-class、 appear-active-class或者 appear-to-class、appear-class、 appear-active-class的排列顺序,此时只有appear-active-class的属性起作用。

2、appear-active-class、appear-class、 appear-to-class

此时appear-active-class的不起作用,由appear-class过渡到appear-to-class属性。

3、appear-class、appear-active-class、 appear-to-class

此时appear-class属性不起作用,由appear-active-class过渡到 appear-to-class属性。

4、 appear-to-class、 appear-active-class、appear-class

此时appear-to-class不起作用,由appear-class过渡到 appear-active-class属性。

在很多情况下,Vue 可以自动得出过渡效果的完成时机。默认情况下,Vue 会等待其在过渡效果的根元素的第一个 transitionend 或 animationend 事件。然而也可以不这样设定——比如,我们可以拥有一个精心编排的一系列过渡效果,其中一些嵌套的内部元素相比于过渡效果的根元素有延迟的或更长的过渡效果。

在这种情况下你可以用 <transition> 组件上的 duration prop 定制一个显性的过渡持续时间 (以毫秒计):

<transition :duration=\”1000\”>…</transition>

你也可以定制进入和移出的持续时间:

<transition :duration=\”{ enter: 500, leave: 800 }\”>

</transition>

上一节我们使用CSS实现的过渡和动画,本节课讲解使用JavaScript钩子函数实现过渡和动画。

JavaScript钩子函数完整过程如下:

  • enter过程:

before-enter:进入过渡前;

enter:过渡运行时;

after-enter:过渡完成后;

enter-cancelled:过渡被打断;

  • leave过程:

before-leave:离开过渡运行前;

leave:离开过渡运行时;

after-leave:离开过渡运行后;

leave-cancelled:离开过渡被打断;

使用示例代码:

<transition

v-on:before-enter=\”beforeEnter\”

v-on:enter=\”enter\”

v-on:after-enter=\”afterEnter\”

v-on:enter-cancelled=\”enterCancelled\”

v-on:before-leave=\”beforeLeave\”

v-on:leave=\”leave\”

v-on:after-leave=\”afterLeave\”

v-on:leave-cancelled=\”leaveCancelled\”

>

<!– … –>

</transition>

/ …

methods: {

// ——–

// 进入中

// ——–

beforeEnter: function (el) {

// …

},

// 当与 CSS 结合使用时

// 回调函数 done 是可选的

enter: function (el, done) {

// …

done()

},

afterEnter: function (el) {

// …

},

enterCancelled: function (el) {

// …

},

// ——–

// 离开时

// ——–

beforeLeave: function (el) {

// …

},

// 当与 CSS 结合使用时

// 回调函数 done 是可选的

leave: function (el, done) {

// …

done()

},

afterLeave: function (el) {

// …

},

// leaveCancelled 只用于 v-show 中

leaveCancelled: function (el) {

// …

}

}

接下来我们来一个一个的看:

示例代码:

<style>

#app div {

width: 200px;

height: 200px;

background-color: antiquewhite;

}

</style>

</head>

<body>

<div id=\”app\”>

<transition @before-enter=\”beforEnter\”>

<div v-show=\”show\”>

我是要显示的内容

</div>

</transition>

<button @click=\”show=!show\”>点击</button>

</div>

</body>

<script>

var count = 0;

new Vue({

el: \’#app\’,

data: {

show: true

},

methods: {

//进入过度前把dom元素设置为字体为红色

beforEnter(el) {

console.log(\’beforEnter触发了\’);

el.style.color = \”red\”;

}

}

})

</script>

程序运行效果如下:

图 8- 5 入场前过渡

该示例代码中钩子函数参数el指的时过渡的元素div,给div设置过渡前的样式。

enter钩子和before-enter稍微有些差异,enter会接受两个参数,语法为enter(el,done),done为回调函数。当before-enter触发完毕后的下一帧,将会真正运行动画效果,整个动画效果也将放到enter这个钩子阶段。

案例:2s后元素字体颜色有红色编程蓝色

示例代码:

<div id=\”app\”>

<transition @before-enter=\”beforEnter\” @enter=\”enterFun\”>

<div v-show=\”show\”>

我是要显示的内容

</div>

</transition>

<button @click=\”show=!show\”>点击</button>

</div>

enterFun(el, done) {

setInterval(() => {

el.style.color = \”blue\”;

}, 2000);

done();//告知动画结束

}

执行时机,在enter过渡进入完成后触发done()回调函数,告知vue动画执行完毕,下一步执行after-enter过渡完成后钩子函数。

示例代码:

<body>

<div id=\”app\”>

<transition @before-enter=\”beforEnter\” @enter=\”enterFun\” @after-enter=\”afterFn\”>

<div v-show=\”show\”>

我是要显示的内容

</div>

</transition>

<button @click=\”show=!show\”>点击</button>

</div>

</body>

<script>

var count = 0;

new Vue({

el: \’#app\’,

data: {

show: true

},

methods: {

//进入过度前把dom元素设置为字体为红色

beforEnter(el) {

console.log(\’beforEnter触发了\’);

el.style.color = \”red\”;

},

enterFun(el, done) {

setTimeout(() => {

el.style.color = \”blue\”;

}, 2000);

setTimeout(() => {

done();//告知动画结束后才会调用下一帧的afterFn

}, 4000);

},

afterFn(el) {

el.style.color = \”purple\”;

}

}

})

</script>

示例代码:

<div id=\”app\”>

<transition @before-enter=\”beforEnter\” @enter=\”enterFun\” @after-enter=\”afterFn\” @enter-cancelled=\”calFn\”>

<div v-show=\”show\”>

我是要显示的内容

</div>

</transition>

<button @click=\”show=!show\”>点击</button>

</div>

calFn() {

console.log(\’calFn\’);

}

当过渡开始的时候,不等过渡执行完毕,打断过渡就会执行enter-cancelled。

出场钩子与入场钩子语法类似,如下:1、before-leave(el)离开过渡运行前2、leave(el,done)离开过渡运行时3、after-leave(el)离开过渡运行后4、leave-cancelled(el)离开过渡被打断时

注意:leave和enter一样,接受两个参数,而且要执行下一帧,必须显示调用done().

如果transition 中包含多个元素,我们来看如何设置:

样式部分设置:

  1. <style>
  2. .v-enter,.v-leave-to{
  3. opacity: 0;
  4. }
  5. .v-enter-active,.v-leave-active{
  6. transition: opacity .5s;
  7. }
  8. </style><!– 分页组件 –>

Html结构部分:

  1. <div id=\”app\”><!– 这有2个div,点击按钮切换显示div内容,   但是需要注意:VUE默认会复用dom元素,导致过渡效果不显示,   解决: 添加唯一值key属性可以标识独立的dom,避免复用     mode是transition自带的属性,可以是out-in 或者 in-out –>
  2. <transition mode=\”out-in\”>
  3. <div v-if=\”show\” key=\”hello\”>hello vue</div>
  4. <div v-else key=\”Bye\”>Bye Vue</div>
  5. </transition>
  6. <button @click=\”handleClick\”>change</button>
  7. </div>

Script部分:

  1. <script>
  2. var vm = new Vue({
  3. el: \’#app\’,
  4. data:{
  5. show: true
  6. },
  7. methods:{
  8. handleClick:function(){
  9. this.show = !this.show;
  10. }
  11. }
  12. })
  13. </script>

以上案例中,要注意,transition中如果多个元素切换,则必须使用key,避免复用。

mode是transition自带的属性,可以是out-in(先出后进) 或者 in-out(先进后出)。

在上一节中,transition中有多个html元素,如果transition中有多个自定义组件时候该如何过渡呢,我们看以下代码:

样式部分设置:

  1. <style>
  2. .v-enter,.v-leave-to{
  3. opacity: 0;
  4. }
  5. .v-enter-active,.v-leave-active{
  6. transition: opacity .5s;
  7. }
  8. </style>

Html结构部分:

  1. <div id=\”app\”>
  2. <transition mode=\”in-out\”>
  3. <!– 动态组件 –>
  4. <component :is=\”type\”></component>
  5. </transition>
  6. <button @click=\”handleClick\”>change</button>
  7. </div>

Script部分:

  1. <script>
  2. Vue.component(\’child\’,{
  3. template: \'<div>child</div>\’
  4. });
  5. Vue.component(\’child-one\’,{
  6. template: \'<div>child-one</div>\’
  7. })
  8. var vm = new Vue({
  9. el: \’#app\’,
  10. data:{
  11. type: \’child\’
  12. },
  13. methods:{
  14. handleClick:function(){
  15. this.type = (this.type === \’child\’?\’child-one\’ : \’child\’);
  16. }
  17. }
  18. })
  19. </script>

该案例中,我们使用动态组件实现切换,其实跟多元素本质是一样的。

如果transition中同时有多个元素或者组件,我们应该使用transition-group,接下来我们来看案例:

例8-6 Demo0806.html

  1. <!DOCTYPE html>
  2. <html lang=\”en\”>
  3. <head>
  4. <meta charset=\”UTF-8\”>
  5. <meta http-equiv=\”X-UA-Compatible\” content=\”IE=edge\”>
  6. <meta name=\”viewport\” content=\”width=device-width, initial-scale=1.0\”>
  7. <title>动画</title>
  8. <!– 在线引入vue.js,必须引入否则无法使用vue–>
  9. <script src=\”https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js\”></script>
  10. <link href=\”https://cdn.jsdelivr.net/npm/animate.css@3.5.1\” rel=\”stylesheet\” type=\”text/css\”>
  11. <style>
  12. .v-enter,
  13. .v-leave-to {
  14. opacity: 0;
  15. }
  16. .v-enter-active,
  17. .v-leave-active {
  18. transition: opacity 1s;
  19. }
  20. </style>
  21. </head>
  22. <body>
  23. <div id=\”app\”>
  24. <transition-group>
  25. <div v-for=\”item of list\” :key=\”item.id\”>
  26. {{item.title}}-{{item.id}}
  27. </div>
  28. </transition-group>
  29. <button @click=\”handleAdd\”>Add</button>
  30. </div>
  31. </body>
  32. <script>
  33. var count = 0;
  34. new Vue({
  35. el: \’#app\’,
  36. data: {
  37. list: []
  38. },
  39. methods: {
  40. handleAdd: function () {
  41. this.list.push({
  42. id: count++,
  43. title: \’hello vue\’
  44. })
  45. }
  46. }
  47. })
  48. </script>
  49. </html>

图 8- 6 列表效果

在该案例中,我们发现每添加一条数据,都有动画过渡。如果使用v-for,并且循环的每个列表在添加和移除的时候需要设置过渡和动画则必须使用transition-group。

过渡可以通过 Vue 的组件系统实现复用。我们可以把一个封装好动画的组件,实现在任何页面的复用。

下面我们来看步骤:

第一步:过渡组件建立:

Vue.component(\’my-special-transition\’, {

template: `

<transition name=\”very-special-transition\” mode=\”out-in\” v-on:before-enter=\”beforeEnter\” @enter=\”enterFn\”

v-on:after-enter=\”afterEnter\”>

<slot v-if=\’status\’></slot>

</transition>

`,

props: [\’status\’],

methods: {

beforeEnter: function (el) {

el.style.color = \”red\”;

},

enterFn(el, done) {

setTimeout(() => {

el.style.color = \’green\’;

}, 2000);

setTimeout(() => {

done();

}, 4000);

},

afterEnter: function (el) {

el.style.color = \”blue\”;

}

}

})

在这我们使用的插槽,因为不确定我们要过渡的内容,在slot上加上v-if=’status’,这个status的值是从根组件上传过来的。

第二步:调用

示例代码:

<div id=\”app\”>

<button @click=\”show = !show\”>切换</button>

<my-special-transition :status=\”show\”>

<p>世界,你好</p>

</my-special-transition>

</div>

完整代码:

<body>

<div id=\”app\”>

<button @click=\”show = !show\”>切换</button>

<my-special-transition :status=\”show\”>

<p>世界,你好</p>

</my-special-transition>

</div>

<script>

Vue.component(\’my-special-transition\’, {

template: `

<transition name=\”very-special-transition\” mode=\”out-in\” v-on:before-enter=\”beforeEnter\” @enter=\”enterFn\”

v-on:after-enter=\”afterEnter\”>

<slot v-if=\’status\’></slot>

</transition>

`,

props: [\’status\’],

methods: {

beforeEnter: function (el) {

el.style.color = \”red\”;

},

enterFn(el, done) {

setTimeout(() => {

el.style.color = \’green\’;

}, 2000);

setTimeout(() => {

done();

}, 4000);

},

afterEnter: function (el) {

el.style.color = \”blue\”;

}

}

})

new Vue({

el: \’#app\’,

data: {

show: false

}

});

</script>

总结:复用过渡组件主要是借助于父子组件的传值。

下面我们来使用学习的过渡动画实现一个简单的小案例:

目标:

  1. 显示列表;
  2. 添加列表动态添加;
  3. 点击列表每一项实现动画删除;

例8-7 Demo0807.html

  1. <!DOCTYPE html>
  2. <html lang=\”en\”>
  3. <head>
  4. <meta charset=\”UTF-8\”>
  5. <meta name=\”viewport\” content=\”width=device-width, initial-scale=1.0\”>
  6. <meta http-equiv=\”X-UA-Compatible\” content=\”ie=edge\”>
  7. <title>Document</title>
  8. <script src=\”https://cdn.jsdelivr.net/npm/vue/dist/vue.js\”></script>
  9. <style>
  10. ul {
  11. list-style: none;
  12. }
  13. li {
  14. border: 1px dashed green;
  15. height: 50px;
  16. line-height: 50px;
  17. margin: 5px;
  18. }
  19. li:hover {
  20. background-color: brown;
  21. transition: all 1s ease;
  22. }
  23. .v-enter,
  24. .v-leave-to {
  25. transform: translateY(70px);
  26. }
  27. .v-enter-active,
  28. .v-leave-active {
  29. transition: all 0.5s ease;
  30. }
  31. .v-move {
  32. transition: all 0.5s ease;
  33. }
  34. </style>
  35. </head>
  36. <body>
  37. <div id=\”app\”>
  38. <label for=\”id\”>
  39. <input type=\”text\” v-model=\”pid\” id=\”id\”>
  40. </label>
  41. <label for=\”name\”>
  42. <input type=\”text\” v-model=\”pname\” id=\”name\”>
  43. </label>
  44. <label>
  45. <input type=\”button\” value=\”添加\” @click=\”addfn\”>
  46. </label>
  47. <ul>
  48. <transition-group>
  49. <li v-for=\”(p,i) in list\” :key=\”p.id\” @click=\”del(i)\”>
  50. {{p.id}} ========== {{p.name}}
  51. </li>
  52. </transition-group>
  53. </ul>
  54. </div>
  55. <script>
  56. //创建Vue实例,得到 ViewModel
  57. var vm = new Vue({
  58. el: \’#app\’,
  59. data: {
  60. pid: \”\”,
  61. pname: \”\”,
  62. list: [
  63. { id: 1001, name: \”陈羽凡\” },
  64. { id: 1002, name: \”胡海泉\” },
  65. { id: 1003, name: \”刘德华\” },
  66. { id: 1004, name: \”成龙\” }
  67. ]
  68. },
  69. methods: {
  70. addfn() {
  71. this.list.push({ id: this.pid, name: this.pname });
  72. this.pid = this.pname = \”\”;
  73. },
  74. del(i) {
  75. this.list.splice(i, 1);
  76. }
  77. }
  78. });
  79. </script>
  80. </body>
  81. </html>

程序运行效果如下:

图 8- 7 过渡效果

本案例,在添加的时候设置了过渡效果,在点击每一条的时候实现过渡删除每一条目;核心代码主要是使用列表过渡。

  • 单元素组件的过渡使用transition标签,以及v-if,v-show,结合Vue过渡实现组件的切换和过渡。动画主要使用CSS动画和第三方动画库。
  • transition里面也可以放多个html元素实现过渡,主要是借助v-if-,v-els–if;
  • javascript的钩子主要有进入过渡的过程以及离开过渡的过程,整个过程包括八个钩子函数;
  • Transition里面也可以放置动态组件,借助于component标签;
  • 借助于Vue的组件系统,也可以在封装组件的时候加上过渡,这样就形成了可复用的过渡组件。

在图书管理系统的基础上:

  • 实现页面打开的时候,添加界面隐藏;
  • 点击添加按钮的时候实现组件过渡出现;
  • 点击删除的时候实现动画删除;

2022年最好的10个JavaScript动画库

如果你想抓住你的网站访问者的注意力,还有什么能比动画更好呢?使用网络上免费提供的许多应用引擎,你可以很容易地让你的网站元素褪色、跳动或嗖嗖作响。在今天的文章中,我们将看到JavaScript动画库如何帮助实现这一切。

首先,介绍一下JavaScript的动画

添加只需要一个动作的简单动画(例如,切换)是一回事。对于这一点,你总是可以使用简单的CSS动画。但是,对于更复杂或高级的效果。 JavaScript是一个更好的工具。不言而喻,使用JavaScript来创建动画比使用CSS更具挑战性。

然而,JavaScript可以处理CSS所不能处理的事情。这给了开发者更多的权力来控制需要协调多个移动部件的复杂动画。

JavaScript动画是通过在一个元素的样式上添加渐变来实现的。你可以把它们作为你代码的一部分在线添加,或者把它们包含在其他对象中。在渲染时,这些变化由一个定时器调用。另外,你可以通过调整变化的时间间隔来控制动画的连续性。

让我们从Anime.js开始这个JavaScript动画库的列表。这个轻量级的动画库在GitHub上有35K多颗星。 通过一个强大的API工作,你可以用它来为HTML、CSS、JS、SVG和DOM属性制作动画。通过一个内置的交错系统,它可以使创建波纹、定向运动、跟随和重叠的效果显得很简单。这个系统在定时和属性上都是可用的。

使用内置的回调和控制函数,你可以做很多事情。例如,你可以同步播放、暂停、控制、逆转和触发事件。

Velocity.js结合了jQuery和CSS转换的优点。它的评分接近17K星,在 GitHub上有接近17K颗星,并拥有像WhatsApp和Motorola这样的杰出用户。 Mailchimp.循环、反转、延迟、隐藏/显示元素、属性数学(+、-、*、/)和硬件加速,都是其功能的一部分。

你可以使用Velocity.js来滚动 browser windows.它既可以与浏览器中加载的jQuery一起工作,也可以独立于它,甚至可以撤消之前的动画效果。

在接近 18K星,Popmotion是一个适用于任何JavaScript环境的功能性动画库。它几乎可以与任何接受数字输入的API一起工作,如 React,Three.js,A-Frame和PixiJS。

Popmotion的重量只有11.7kB,但却很有冲击力。它的特点是动画,如关键帧、衰减、用于同步多个实例的时间线等。你可以错开任何系列的动画或函数,也可以使用纯函数来组成你自己的配置。

Three.js以60K以上的星级在这个JavaScript动画库列表中排名第一。 它依靠的是 WebGL来创建和渲染浏览器中的3D动画。

有大量的文档可以帮助你,一旦你通过了学习曲线,使用这个库就没有什么不能完成的。首先,使用Three.js编辑器,你可以创建一个场景。此后,你可以添加几何图形,并调整灯光和摄像机。材料、纹理、物体、颜色和雾化都可以进行调整,最后的文件可以发布到你的项目中。

GreenSock的GSAP与一组小的JavaScript文件一起工作,使动画在所有主要的浏览器中看起来很好。它能顺利地将多个动画属性连接起来,并消除浏览器的错误。

GSAP的动作包括在Canvas上创建动画,以及为场景中的任何对象制作动画。还可以逐步揭示、变形或沿路径移动任何对象。为此,它与一堆软件应用一起工作,如SVGPlugins、PixiPlugin、WebGL、Adobe Animate和EaseJS。它的模块化结构有助于你选择你需要的功能。拥有800万用户和10K+颗星的 GitHub上有800万用户和10K多颗星,这个强大的库有很多优点。

6. AniJS

在这个列表中的JavaScript库中,AniJS有些独特。它允许你在一个简单的 \”句子 \”结构中为元素添加动画,这对刚接触动画的人来说是很好的。更重要的是,它的非特定性质使得几乎每个人都可以在日常的用户体验设计中使用它。

GitHub,AniJS的评分超过了3.5K星。它不依赖任何第三方库,通常有助于加快开发速度。它在安卓和iOS上都能很好地工作。 Android and iOS,也可以在所有流行的浏览器中使用。

7. Mo.js

运动图形在动画中起着很大的作用,Mo.js是一个可以让你产生影响的选择。由于有大量的教程和演示帮助,初学者可能不会发现创建几何形状和时间动画的难度。

这些API可能看起来很简单,但你可以用它们做很多事情。在这个工具包中,你会发现一个曲线编辑器和时间线编辑器来帮助你建立你的动画,以及一个播放器来控制你的动画。有不同的模块用于交错、缓和、时间线和更多。所有这些为Mo.js赢得了接近16K星的评价。

8. Vivus.js

如果你想在屏幕上实时地模仿钢笔画,你会用Vivus达到目的。它可以让你对SVG进行动画处理,给人以被绘制的感觉。由于它没有任何依赖性,所以它是快速和轻便的。

你可以选择任何一种可用的动画 – 延迟、同步或OneByOne。否则,你也可以创建一个自定义脚本来绘制你的SVG。为了提高灵活性,你可以用一个简单的JavaScript函数来覆盖每个路径的动画。超过1.3万名用户对这个库竖起了大拇指。

9. ScrollReveal JS

如果你希望在你的网页元素滚动进入视图时为它们制作动画,ScrollReveal不会让你失望。这个简单易学的动画库没有任何依赖性,在GitHub上有18.5K多颗星。

ScrollReveal支持不同类型的效果,在网络和移动浏览器上运行良好。它故意用一个裸露的配置来工作,所以你可以把它作为你的创造力的画布。为了使动画的效果最大化,创作者建议你少用它。

10. Typed.js

Typed.js是一个简单的库(更像是一个插件,真的),用于在你的屏幕上对打字进行动画处理。一旦你输入任何字符串,访问者就可以看到它以设定的速度被打出来。不仅如此,你还可以操作退格按钮,以及开始一个新的句子。如果你希望让禁用JS的访问者也能看到,你只需要在页面上放置一个HTML div。这样一来,机器人和搜索引擎也能查看输入的文字。

该库在GitHub的评分为9.5K+星,强大的用户包括Slack和Envato。

11. Lottie by AirBnB

Lottie是一种轻量级的动画图形格式,平衡了高质量的图形和渲染成本。它使应用程序更小,并包括动态功能。它可以用于网络、安卓、iOS和物联网,不需要额外的软件。

Lottie可以在任何支持JavaScript的浏览器上运行。动画是以纯文本形式存储的,是人类可读的。由于文本数据是以JSON格式存储的,它很容易被任何JavaScript环境同化。这使得它成为一种流行的动画图形格式,以增强移动前端。仅仅是安卓版本就有接近3万颗星。

jQuery slideToggle() 方法用法详解

slideToggle() 是 jQuery 中用于实现滑动效果的动画方法。它可以在指定的元素上切换显示和隐藏状态,同时伴随着平滑的滑动动画。这个方法非常适合用于创建可折叠面板、菜单等交互组件。

  • selector:选择器,用于指定要应用动画的元素。
  • duration(可选):动画执行的时间,以毫秒为单位。默认值是 400 毫秒。
  • callback(可选):动画完成后的回调函数。

以下是一些使用 slideToggle() 方法的示例:

在这个示例中,点击按钮时会触发 slideToggle() 方法,使内容区域在显示和隐藏之间切换。

在这个示例中,slideToggle() 方法带有一个持续时间参数(1000 毫秒),并在动画完成后弹出一个提示框。

  1. 初始状态:如果目标元素的初始状态是 display: none,那么 slideToggle() 会将其显示出来;如果初始状态是 display: block 或其他可见状态,则会将其隐藏。
  2. 高度依赖slideToggle() 依赖于元素的当前高度来计算动画效果。因此,确保元素的高度是可计算的。
  3. 性能考虑:对于大量元素的动画操作,要注意性能问题,避免频繁调用或在低性能设备上使用。

slideToggle() 是一个简单而强大的方法,适用于需要平滑过渡效果的场景。通过合理设置参数和回调函数,可以实现丰富的交互效果。

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。