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的组件系统,也可以在封装组件的时候加上过渡,这样就形成了可复用的过渡组件。

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

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

不懂代码也能做出酷炫可视化大屏

最近在做一个数据可视化大屏项目,从指标设计、视觉设计、可视化动效到大屏硬件、开发工具整个流程,总结了一些经验和观点,想和大家分享。

大屏制作工具

大屏的制作,可以用代码开发或现成的可视化工具来实现。

用的比较多的就是JS+Ecahrts,但数据量支撑、后台响应、实时更新、平台运维等应该还要调用更多的技术,这个不是非常懂就不赘述了。

另一种是用现成的可视化工具,能相对简单高效的搭建一个数据大屏,比如帆软FineReport,阿里dataV。

大屏硬件

大屏的展示工具几乎都是LED拼接屏,如果是boss办公室这种也有用大屏幕显示器的。

用LED拼接屏,UI设计时不用考虑屏幕缝隙影响内容的呈现,内容不会丢失,但有可能影响视觉的表现。设计时需要建立缝隙位置的参考线避,免类重要信息被分割。现在企业常用的有无缝隙、1.7mm缝隙、3.5mm缝隙、三种拼接大屏,缝隙越小越贵。

拼接的每块小屏一般是16:9的高清屏,设计尺寸可以把上下高度设定为1080px,长度按照拼接屏的数量比例得出长度的设计尺寸。例如3乘5的一块大屏幕,高度3块屏设为1080,每块高就是360,360除9乘16等640,640就是一块屏幕的长度,640乘5块屏=3200最后得出设计稿尺寸就是:高1080px乘宽3200px。

下图是天猫可视化大屏设计,图中屌炸天的3D地球围绕粒子效果。

接下来就来讲讲制作可视化大屏的重头戏,指标、布局、设计、动效。以FineReport制作大屏为例,这篇文章将教你怎么实现可视化。

指标设计

设计大屏,大家可能会被酷炫的可视化所感动,但一定要谨记,大屏一定是以展示数据为核心,任何炫酷屌炸天的表现都要建立在不影响数据的有效展示上!

所以,大屏首要考虑的是放哪些数据,那么多指标应该放那些?

一般而言,一个大屏一定会有明确的主题,比如销售数据大屏,集团营业数据大屏。针对这种主题明确的可视化,推荐一个非常好用的套路——多维度拆解北极星指标法

第一步:确定一个北极星指标。如销售大屏,你的销售总额一定是最重要的吧,这就是主题。

第二步:多维度拆解北极星指标,把你的销售额情况分解。

从时间的维度。每个季度每个月的销售额情况是如何,销售额特别高的时间段,原因是什么,做了哪些措施?

从地理维度。各大区域销售额情况如何?可以做个排名情况。

从计划维度。和年初定的计划相比,差了多少?

从占比维度。各个产品占的销售额多少,哪些是带来贡献最多的明星产品。

布局

布局的目的是为了让业务指标和数据合理的展现。由于往往展现的是一个全局的业务,一般分为主要指标和次要指标两个层次,主要指标反映核心业务,次要指标用于进一步阐述分析,所以在制作时给予不一样的侧重。

这里推荐几种常见的版式:

上面几个版式不是金科定律,只是通常推荐的主次分布版式,能让信息一目了然。实际情况中,不一定使用主次分布,也可以使用平均分布,或者可以二者结合进行适当调整。比如下图所示,指标很多很多,存在多个层级的,就根据上面所说的基本原则进行一些微调,效果会很好。

视觉设计

设计的风格,背景色一般用深色调,深色调紧张感强,让视觉更好的聚焦,大屏暗色调看上去更柔和舒服不刺眼,也会较省电。

大屏设计跟网页不一样,页面不能有滚动条,大屏的长宽都是固定的。

字号跟网页设计一样不小于12号字,可以用于图表的标注,数据信息建议14号字以上,大屏观者远距离才能看全内容,所以字号可以稍大一点。字体不一定只用一种,可以用到一些科技感强的字体,这里要注意,记得把字体给开发一份。

设计完成先去大屏上看一下效果,大屏的品质不一样色调也会有很大的差别,要根据自家的大屏呈现效果做调整。

可以去看一个开源的jquery插件库网站,里面有很多很棒的动态效果!

交互设计

我把大数据可视化大屏分为两种,一种“纯展示型”另一种“展示+功能型”。纯展示型几乎没有交互,后台录入数据,在大屏上展示就行了。展示+功能型,例如实时监控数据、采集数据、数据对比功能、云计算数据、分析与预警等等。

这里着重说一下带有功能型的大屏产品的结构层(信息架构)。一切功能结构都要围绕核心数据主页面来架构,因为大屏展示的核心就是将一些业务的关键指标数据以数据可视化的方式展示出来。

动效设计

大数据可视化大屏设计少不了动效,动效是可视化重要的组成部分,动效的增加能让大屏看上去是活的,增加观感体验。但过分的动效极其容易喧宾夺主,让观看者的眼球不知道往哪里聚焦,反而弱化了数据的展示。

其实,把握动效设计这个度其实并不难,只要看的舒服不影响数据清晰展示就可以,有数据展示的页面最好动的地方不易过多,如果要多,几个动画就得有节奏的变化,例如一个动画表现的视觉强,另一个就表现稍弱化,有强有弱、有主有次节奏才会舒服,同时动效能结合数据的变化而变化最好,这样就不容易看数据内容被动画抓走眼球。

动效怎么实现?

我习惯用AE的插件Bodymovin生成json文件实现。

这里用FineReport做大屏自带一些可视化动效:

3D动效怎么实现?

如果自己开发,用软件C4D+AE+PS,先建模选软再导入AE视觉稿。这里我就用了FineReport自带的3D动效。无非就是个炫,放一两个就够了。

3D地球可视化

开篇给大家留个悬念,怎么设计3D地球动画。天猫双十一阿里的3D地球是有专门人员设计的,阿里也有这方面的组件库。我们可以用开源网站类似组件来实现,大数据页面用到的图表这个网站几乎都有,且免费。最终的效果是用两个组件拼合在一起实现的,左边就是代码,后台录入信息可以让粒子效果匹配数据,最终实现数据的可视化。

同样有很多的图表组件,可以用Echarts和Highcharts。前者免费、开源、效果炫酷、原生全中文,但兼容性差、经常报错、文档不够详情。或者用更强大的Highcharts,优点是文档实例很详细、易懂易学、兼容性强可兼容到IE6,但是收费。

下图是我用FineReport做项目时的3D地球可视化插件。

最后,附上几张FineReport的大屏图。带自动播放效果及3D动画特效的数据可视化!

FineReport的大屏可以离屏用ipad控制,做到内容交互,简直是业务演示汇报的利器!

实际应用场景。

总结

大屏设计是一个长期跟进的过程,有很多问题会在数据真正进来时,放在大屏上才能发现,所以等产品做到落地时设计方面要积极跟进改进。

好了就这么多感谢阅读,希望这篇文章对你有一点用!想尝试大屏制作的,先从下载FineReport学做dashboard开始吧。

10个酷炫图像悬停动画特效「值得收藏」

作者:semlinker

转发链接:https://mp.weixin.qq.com/s/p0U8sVLtWd78CLc8kM22FQ

本文小编将给大家介绍10个 图像悬停效果,希望小编精心录制的十个 Gif 动画能让大家眼前一亮,当然更希望这些特效能给大家设计图片悬停效果带来一些 「”灵感“」

示例说明:该示例会根据鼠标移入的方向展示不同的动画效果。

示例来源:Noel Delgado

在线地址:https://codepen.io/noeldelgado/pen/pGwFx

「静态效果图」

「Gif 动态效果图」

示例说明:当鼠标悬停在图片上时,会产生 3D 的堆叠运动效果。

示例来源:https://tympanus.net/

在线地址:https://tympanus.net/Development/StackMotionHoverEffects/

「静态效果图」

「Gif 动态效果图」

示例说明:当鼠标悬停在 3D 的网格图片上时,会产生 3D 的堆叠效果。

示例来源:https://tympanus.net

在线地址:https://tympanus.net/Development/IsometricGrids/

「静态效果图」

「Gif 动态效果图」

示例说明:当鼠标悬停在图片上时,会产生 3D 的折叠效果。

示例来源:https://tympanus.net/

在线地址:https://tympanus.net/Tutorials/3DHoverEffects/

「静态效果图」

「Gif 动态效果图」

示例说明:鼠标悬停图片时显示相应的文字介绍。

示例来源:LittleSnippets.net

在线地址:https://codepen.io/littlesnippets/pen/bpMmBO

「静态效果图」

「Gif 动态效果图」

示例说明:鼠标悬停图片时,图片会有滑动效果。

示例来源:LittleSnippets.net

在线地址:https://codepen.io/littlesnippets/pen/dGVQvB

「静态效果图」

「Gif 动态效果图」

示例说明:鼠标悬停在背景图片上,滑动会显示前景图。

示例来源:Hervé

在线地址:https://codepen.io/herve/pen/GoEna

「静态效果图」

「Gif 动态效果图」

示例说明:使用 CSS3 和 jQuery 实现放大镜效果。

示例来源:Rohan Hapani

在线地址:https://codepen.io/desirecode/pen/vgwaoe

「静态效果图」

「Gif 动态效果图」

示例说明:悬停引导按钮时,显示其他的功能菜单。

示例来源:Jouan Marcel

在线地址:https://codepen.io/jouanmarcel/pen/NLgVjm

「静态效果图」

「Gif 动态效果图」

示例说明:悬停引导按钮时,显示其他的功能菜单。

示例来源:Shaw

在线地址:https://codepen.io/shshaw/pen/RyOPzb

「静态效果图」

「Gif 动态效果图」

在日常工作中,如果小伙伴们也想实现图片悬停特效,小编推荐一个 Github 上的一个可扩展的、轻量的 CSS 图片悬停动画库 ——「imagehover.css」 。该库是一个制作精良的 CSS 库,允许你轻松实现各种图片悬停效果,支持 「40」 个悬停效果,压缩后仅有 「19KB」

作者:semlinker

转发链接:https://mp.weixin.qq.com/s/p0U8sVLtWd78CLc8kM22FQ

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

点赞 0
收藏 0

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