SPA 中组件的切换有一种生硬的隐藏显示感受,为了更好的用户体验,让组件切换时淡出淡入,Vue 提供了专门的组件 transition。javascript
每一个状态在使用的时候都是在 CSS 中使用,结合组件 transition 的 name 属性。如 <transition name="fade"></transition>
,对应的是 fade-
加上每一个状态:fade-enter
。css
使用到组件 transition
的属性: name
。html
<style type="text/css" media="screen"> /*初始状态*/ .fade-enter{opacity: 0;} /*已经准备就绪*/ .fade-enter-active{transition: all .5s;} /*已经消失*/ .fade-leave-active{opacity: 0; transition: all .5s;} </style> <div id="app"> <input type="button" :value="show ? 'hide' : 'show'" @click="show = !show" /> <br/> <transition name="fade"> <img src="imgs/green.jpg" v-show="show" /> </transition> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { show: true } }) </script>
效果预览vue
使用到组件 transition
的属性: name
。java
<style type="text/css" media="screen"> .fade-enter-active{animation: fade-in .5s;} .fade-leave-active{animation: fade-out .5s;} @keyframes fade-in{ from{ opacity: 0; } to{ opacity: 1; } } @keyframes fade-out{ from{opacity: 1;} to{opacity: 0;} } </style> <div id="app"> <input type="button" :value="show ? 'hide' : 'show'" @click="show = !show" /> <br/> <transition name="fade"> <img src="imgs/green.jpg" v-if="show" /> </transition> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { show: true } }) </script>
效果预览git
第一次加载时的过渡效果,使用到组件 transition
的属性: appear
appear-class
appear-active-class
。github
<style type="text/css" media="screen"> .fade-enter{opacity: 0;} .fade-enter-active{transition: all 3s;} </style> <div id="app"> <transition appear appear-class="fade-enter" appear-active-class="fade-enter-active"> <img src="imgs/green.jpg" /> </transition> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app' }) </script>
效果预览app
同时生效的进入和离开的过渡不能知足全部要求,因此 Vue 提供了 过渡模式:dom
使用到组件 transition
的属性: mode
。ide
<style type="text/css" media="screen"> .fade-enter{opacity: 0;} .fade-enter-active{transition: all .5s;} .fade-leave-active{opacity: 0; transition: all .5s;} </style> <div id="app"> <fieldset> <legend><h3>mode = in-out</h3></legend> <div> <input type="button" :value="red ? 'green' : 'red'" @click="red = !red" /> <br/> <transition name="fade" mode="in-out"> <img src="imgs/red.jpg" v-if="red" key="red"/> <img src="imgs/green.jpg" v-else key="green"/> </transition> </div> </fieldset> <fieldset> <legend><h3>mode = out-in</h3></legend> <div> <input type="button" :value="flag == 1 ? 'green' : flag == 2 ? 'yellw' : 'red'" @click="flag = flag == 1 ? 2 : flag == 2 ? 3 : 1" /> <br/> <transition name="fade" mode="out-in"> <img src="imgs/red.jpg" v-if="flag == 1" key="red"/> <img src="imgs/green.jpg" v-else-if="flag == 2" key="green"/> <img src="imgs/yellow.jpg" v-else key="yellow" /> </transition> </div> </fieldset> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { red: true, flag: 1 } }) </script>
v-for 生成列表过渡效果要使用组件 transition-group
,组件提供属性 tag
表示该组件将会渲染成对应的 DOM 节点,其它的使用和 transition
同样。
<style type="text/css" media="screen"> *{list-style: none;} li{width: 300px; margin-bottom: 5px; padding: 10px 20px; background-color: #ccc;} .list-enter{opacity: 0; transform: translateX(300px);} .list-enter-active{transition: all .5s;} .list-leave-active{transition: all .5s; opacity: 0; transform: translateX(-300px);} </style> <div id="app"> <p> <input type="button" value="AddItem" @click="addItem"> <input type="button" value="RemoveItem" @click="removeItem"> </p> <transition-group tag="ul" name="list"> <li v-for="(item, index) in items" :key="item">Item {{index}}</li> </transition-group> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { items: [1,2,3] }, methods: { randomIndex: function(){ return parseInt(this.items.length * Math.random()); }, addItem: function(){ this.items.splice(this.randomIndex(), 0, this.items.length + 1); }, removeItem: function(){ this.items.splice(this.randomIndex(), 1); } } }) </script>
咱们能够经过如下特性来自定义过渡类名:
他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其余第三方 CSS 动画库,如 Animate.css 结合使用十分有用。
<link rel="stylesheet" type="text/css" href="animate.css"> <div id="app"> <button @click="show = !show">Toggle render</button> <transition enter-active-class="animated jello" leave-active-class="animated bounceOutRight"> <div v-if="show"><img src="./imgs/green.jpg" /></div> </transition> </div> <script type="text/javascript"> var vm = new Vue({ el: '#app', data: { show: true } }) </script>
除了用CSS过渡的动画来实现vue的组件过渡,还能够用JavaScript的钩子函数来实现,在钩子函数中直接操做DOM。咱们能够在属性中声明如下钩子:
<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> <script type="text/javascript"> var vm = new Vue({ el: '#app', methods: { // 过渡进入 // 设置过渡进入以前的组件状态 beforeEnter: function (el) { // ... }, // 设置过渡进入完成时的组件状态 enter: function (el, done) { // ... done() }, // 设置过渡进入完成以后的组件状态 afterEnter: function (el) { // ... }, enterCancelled: function (el) { // ... }, // 过渡离开 // 设置过渡离开以前的组件状态 beforeLeave: function (el) { // ... }, // 设置过渡离开完成时地组件状态 leave: function (el, done) { // ... done() }, // 设置过渡离开完成以后的组件状态 afterLeave: function (el) { // ... }, // leaveCancelled 只用于 v-show 中 leaveCancelled: function (el) { // ... } } }) </script>