看一下文档中key [TOC] >[success] # transition -- Vue的过渡动画 ~~~ 1.这里面的transition 是vue所属标签,所以是在vue中才可以使用 2.什么场景可以使用transition : 2.1条件渲染 (使用 v-if) 2.2条件展示 (使用 v-show) 2.3动态组件 2.4组件根节点 ~~~ >[info] ## transition 使用 ~~~ 1.整个使用笔者自己将它分为三种,第一种是全程动画有去有回,第二种半程 动画,只去或者只回,第三种使用第三方动画库'Animate.css ' ~~~ >[danger] ##### 第一种自定义全程动画 * 概念理解 ~~~ 1.解释下笔者说的全程动画,是整个动画有来有回,简单的理解,有一个按 钮控制了一个数据的显示和隐藏,当第一次点击这个按钮,让信息显示的时 候会执行一个显示的过场动画,第二次点击这个按钮,内容就会隐藏,但这 个隐藏动画起始展示位置会在你第一次显示位置的基础上执行。 2.简单的说动画是反复交替的,也就是整体构成会有两次,下面的案例会说 明上面的解释 ~~~ * 使用方法 ~~~ 1.根据上面分析,可以勾勒出动画执行的时间效果图,最开始进入动画 进入 之前,'元素的起始状态' --- 》'入场动画的时间段'--》'离场动画的时间段' --》 '画离开之后,离开的终止状态' 2.下面官方的图可以更直观的说明 3.将官方规定的执行顺序class 做一个具体说明: 3.1 v-enter 【这是一个时间点】 是进入之前,元素的起始状态,此时还 没有开始进入 3.2.v-enter-active 【入场动画的时间段】 3.3 v-leave-to 【这是一个时间点】 是动画离开之后,离开的终止状态, 此时,元素 动画已经结束了 3.4.v-leave-active 【离场动画的时间段】 ~~~ ![](https://box.kancloud.cn/ae162747a2cf33ddfd48cf2bb0440948_678x255.png) * 案例 ![](https://box.kancloud.cn/8a246e33f7b66a2245825cc180f9ba10_235x93.png) ~~~ 1.其实下面案例可以整合写在一起,由于防止整合写法让思维固化,认为不 能拆分单独定义每个阶段,下面案例采用的就是不是整合写法 2.下面的效果解释,当动画进入的时候从0-1整体0.6s显示,当第二次点击, 隐藏的时候接着上次从1-0 整体用时1s 3.整合写法: .v-enter-active, .v-leave-active{ transition: all 1s ease; } .v-leave-to { opacity: 0; } ~~~ ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> <style> .v-enter{ opacity: 0; /*刚开始还没进入的时候透明度为零*/ } .v-enter-active{ transition: all 0.6s ease; } .v-leave-active{ transition: all 1s ease; } .v-leave-to{ opacity: 0; } </style> </head> <body> <div id="app"> <button @click="flag=!flag">执行往返动画</button> <transition> <p v-if="flag">我是那段被执行的往返动画</p> </transition> </div> </body> <script> let vm = new Vue({ el:"#app", data:{ flag:false, } }) </script> </html> ~~~ >[danger] ##### 第二种半程动画 ~~~ 1.有时候执行动画的时候,只想执行半程,举个例子,当下订单购物的时 候,点击商品好多时候,商品会有一个动画效果进入购物车,如果 这种, 采用了全程动画,第二次点击的时候小球就会从购物车出来,但其实这不是 我们想要的,我们想要的不管第几次点击小球都是从商品到购物车。 2.半程动画也就可以实现调用一些第三方动画效果的js,让实现通过js调用, 实现全程动画,因为半程动画是在方法中写的而不是css中。 ~~~ * 使用方法(JavaScript 钩子) ~~~ 1.首先半程动画都是函数,因此v-on绑定指定的钩子事件,执行自己定义的 事件方法。 2.使用写法: <transition v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:after-enter="afterEnter" celled" v-on:before-leave="beforeLeave" v-on:leave="leave" v-on:after-leave="afterLeave" ancelled" > <!-- ... --> </transition> 3.参数介绍: methods: { // 注意beforeEnter参数el是绑定对象的dom // 表示动画入场之前,此时,动画尚未开始,可以 在 beforeEnter 中,设 置元素开始动画之前的起始样式 beforeEnter: function (el) { }, // enter 表示动画 开始之后的样式,这里,可以设置小球完成动画之后的,结束状态 // 这里的 done, 起始就是 afterEnter 这个函数,也就是说:done 是 afterEnter 函数的引用 //el.offsetWidth 会强制动画刷新,没有实际的作用,但是,如果不写,出不来动画效果; enter: function (el, done) { el.offsetWidth done() }, //控制小球的显示与隐藏 afterEnter: function (el) { // ... }, beforeLeave/leave/afterLeave 和上面类似只不过这里相当于往返动画的第 二阶段 ~~~ * 特别解释下执行顺序 ~~~ 1.首先beforeEnter 中的el参数来规定dom初始画的位置颜色等基础值, enter 中的el参数来规定动画的效果值,done参数来调用afterEnter,而 afterEnter 函数用了执行控制显示隐藏的data值变化。主要的功能第二次点 击按钮的时候,实际是吧在enter执行done时候的数值再次变回初始值 ~~~ ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script> <style> .ball { width: 15px; height: 15px; border-radius: 50%; background-color: red; } </style> </head> <body> <div id="app"> <input type="button" value="快到碗里来" @click="flag=!flag"> <!-- 1. 使用 transition 元素把 小球包裹起来 --> <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter"> <div class="ball" v-show="flag"></div> </transition> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { flag: false }, methods: { // 注意: 动画钩子函数的第一个参数:el,表示 要执行动画的那个DOM元素,是个原生的 JS DOM对象 // 大家可以认为 , el 是通过 document.getElementById('') 方式获取到的原生JS DOM对象 beforeEnter(el){ // beforeEnter 表示动画入场之前,此时,动画尚未开始,可以 在 beforeEnter 中,设置元素开始动画之前的起始样式 // 设置小球开始动画之前的,起始位置 el.style.transform = "translate(0, 0)" }, enter(el, done){ // 这句话,没有实际的作用,但是,如果不写,出不来动画效果; // 可以认为 el.offsetWidth 会强制动画刷新 el.offsetWidth // enter 表示动画 开始之后的样式,这里,可以设置小球完成动画之后的,结束状态 el.style.transform = "translate(150px, 450px)" el.style.transition = 'all 1s ease' // 这里的 done, 起始就是 afterEnter 这个函数,也就是说:done 是 afterEnter 函数的引用 done() }, afterEnter(el){ // 动画完成之后,会调用 afterEnter // console.log('ok') // 这句话, 第一个功能,是控制小球的显示与隐藏 // 第二个功能: 直接跳过后半场动画,让 flag 标识符 直接变为 false // 当第二次再点击 按钮的时候, flag false -> true this.flag = !this.flag // el.style.opacity = 0.5 // Vue 把一个完整的动画,使用钩子函数,拆分为了两部分: // 我们使用 flag 标识符,来表示动画的切换; // 刚以开始,flag = false -> true -> false } } }); </script> </body> </html> ~~~ >[danger] ##### 第三种使用第三方样式包animate.css ~~~ 1. 去官网找对应的animate动画效果即可 ~~~ ~~~ <script src="./lib/vue-2.4.0.js"></script> <link rel="stylesheet" href="./lib/animate.css"> <!-- 入场 bounceIn 离场 bounceOut --> </head> <body> <div id="app"> <input type="button" value="toggle" @click="flag=!flag"> <!-- 需求: 点击按钮,让 h3 显示,再点击,让 h3 隐藏 --> <!-- <transition enter-active-class="animated bounceIn" leave-active-class="animated bounceOut"> <h3 v-if="flag">这是一个H3</h3> </transition> --> <!-- 使用 :duration="毫秒值" 来统一设置 入场 和 离场 时候的动画时长 --> <!-- <transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration="200"> <h3 v-if="flag" class="animated">这是一个H3</h3> </transition> --> <!-- 使用 :duration="{ enter: 200, leave: 400 }" 来分别设置 入场的时长 和 离场的时长 --> <transition enter-active-class="bounceIn" leave-active-class="bounceOut" :duration="{ enter: 200, leave: 400 }"> <h3 v-if="flag" class="animated">这是一个H3</h3> </transition> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { flag: false }, methods: {} }); </script> </body> </html> ~~~ >[info]## 自定义transition ~~~ 1可以自定义多个动画效果使用 2.在被包裹的transition 加那么属性 3.使用的时候 加对应的name 前缀 ~~~ >[danger] ##### 案例 ~~~ <script src="./lib/vue-2.4.0.js"></script> <!-- 2. 自定义两组样式,来控制 transition 内部的元素实现动画 --> <style> /* v-enter 【这是一个时间点】 是进入之前,元素的起始状态,此时还没有开始进入 */ /* v-leave-to 【这是一个时间点】 是动画离开之后,离开的终止状态,此时,元素 动画已经结束了 */ .v-enter, .v-leave-to { opacity: 0; transform: translateX(150px); } /* v-enter-active 【入场动画的时间段】 */ /* v-leave-active 【离场动画的时间段】 */ .v-enter-active, .v-leave-active{ transition: all 0.8s ease; } .my-enter, .my-leave-to { opacity: 0; transform: translateY(70px); } .my-enter-active, .my-leave-active{ transition: all 0.8s ease; } </style> </head> <body> <div id="app"> <input type="button" value="toggle" @click="flag=!flag"> <!-- 需求: 点击按钮,让 h3 显示,再点击,让 h3 隐藏 --> <!-- 1. 使用 transition 元素,把 需要被动画控制的元素,包裹起来 --> <!-- transition 元素,是 Vue 官方提供的 --> <transition> <h3 v-if="flag">这是一个H3</h3> </transition> <hr> <input type="button" value="toggle2" @click="flag2=!flag2"> <transition name="my"> <h6 v-if="flag2">这是一个H6</h6> </transition> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { flag: false, flag2: false }, methods: {} }); </script> </body> </html> ~~~ >[info] ## 给v-for 增加transition效果 ~~~ 1.多个元素过渡(设置key)当有相同标签名的元素切换时,需要通过 key 特 性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相 同标签内部的内容。mode:in-out ; out-in 2.列表过渡(设置key)<transition-group>不同于 transition, 它会以一个真实 元素呈现:默认为一个 <span>。你也可以通过 tag 特性更换为其他元素。 提供唯一的 key 属性值 ~~~ >[danger] ##### 案例 ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="./lib/vue-2.4.0.js"></script> <style> li { border: 1px dashed #999; margin: 5px; line-height: 35px; padding-left: 5px; font-size: 12px; width: 100%; } li:hover { background-color: hotpink; transition: all 0.8s ease; } .v-enter, .v-leave-to { opacity: 0; transform: translateY(80px); } .v-enter-active, .v-leave-active { transition: all 0.6s ease; } /* 下面的 .v-move 和 .v-leave-active 配合使用,能够实现列表后续的元素,渐渐地漂上来的效果 */ .v-move { transition: all 0.6s ease; } .v-leave-active{ position: absolute; } </style> </head> <body> <div id="app"> <div> <label> Id: <input type="text" v-model="id"> </label> <label> Name: <input type="text" v-model="name"> </label> <input type="button" value="添加" @click="add"> </div> <!-- <ul> --> <!-- 在实现列表过渡的时候,如果需要过渡的元素,是通过 v-for 循环渲染出来的,不能使用 transition 包裹,需要使用 transitionGroup --> <!-- 如果要为 v-for 循环创建的元素设置动画,必须为每一个 元素 设置 :key 属性 --> <!-- 给 transition-group 添加 appear 属性,实现页面刚展示出来时候,入场时候的效果 --> <!-- 通过 为 transition-group 元素,设置 tag 属性,指定 transition-group 渲染为指定的元素,如果不指定 tag 属性,默认,渲染为 span 标签 --> <transition-group appear tag="ul"> <li v-for="(item, i) in list" :key="item.id" @click="del(i)"> {{item.id}} --- {{item.name}} </li> </transition-group> <!-- </ul> --> </div> <script> // 创建 Vue 实例,得到 ViewModel var vm = new Vue({ el: '#app', data: { id: '', name: '', list: [ { id: 1, name: '赵高' }, { id: 2, name: '秦桧' }, { id: 3, name: '严嵩' }, { id: 4, name: '魏忠贤' } ] }, methods: { add() { this.list.push({ id: this.id, name: this.name }) this.id = this.name = '' }, del(i) { this.list.splice(i, 1) } } }); </script> </body> </html> ~~~