通过 appear attribute 设置节点在初始渲染的过渡
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>
appear + js钩子
<transition appear v-on:before-appear="customBeforeAppearHook"v-on:appear="customAppearHook" v-on:after-appear="customAfterAppearHook"v-on:appear-cancelled="customAppearCancelledHook" > <!-- ... --> </transition>
v-if 或者 v-show 条件显示或者动态组件下可以添加进入/离开过渡
<div id="demo"> <button v-on:click="show = !show">Toggle</button> <transition name="fade"> <p v-if="show">hello</p> </transition> </div> <script> new Vue({ el: '#demo', data: {show: true } }) </script> <style> /* 定义进入 /离开的过渡动作 */ .fade-enter-active, .fade-leave-active {transition: opacity .5s;} /* .fade-leave-active below version 2.1.8 */ .fade-enter, .fade-leave-to {opacity: 0;} </style>
CSS 动画用法同 CSS 过渡,区别是在动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在 animationend 事件触发时删除。
<div id="demo"> <button v-on:click="show = !show">Toggle</button> <transition name="bounce"> <p v-if="show">hello</p> </transition> </div> <script> new Vue({ el: '#demo', data: {show: true } }) </script> <style> /* 定义进入 / 离开的动画 */ .bounce-enter-active { animation: bounce-in .5s; } .bounce-leave-active { animation: bounce-in .5s reverse; } @keyframes bounce-in { 0% {transform: scale(0);} 50% {transform: scale(1.5);} 100% {transform: scale(1);} } </style>
在一些场景中,你需要给同一个元素同时设置两种过渡动效,比如
animation
很快的被触发并完成了,而transition
效果还没结束。在这种情况中,你就需要使用type
attribute 并设置animation
或transition
来明确声明你需要 Vue 监听的类型。
多个原生标签可以使用 v-if/v-else:
最常见的多标签过渡是一个列表和描述这个列表为空消息的元素:
<transition> <table v-if="items.length > 0"> <!-- ... --> </table> <p v-else>Sorry, no items found.</p> </transition>
相同标签名的元素切换时,需要通过 key attribute 设置唯一的值
<transition> <button v-if="isEditing" key="save">Save</button> <button v-else key="edit">Edit</button> </transition> <!-- 也可以通过给同一个元素的 key attribute 设置不同的状态 --> <transition> <button v-bind:key="isEditing">{{ isEditing ? 'Save' : 'Edit' }}</button> </transition>
多个组件的过渡可以使用动态组件:
<div id="comp"> <radio v-model="view" value="v-a">A</radio> <radio v-model="view" value="v-b">B</radio> <transition name="component-fade" mode="out-in"> <component v-bind:is="view"></component> </transition> </div> <script> new Vue({ el: '#transition-components-demo', data: {view: 'v-a'}, components: { 'v-a': { template: '<div>Component A</div>' }, 'v-b': { template: '<div>Component B</div>' } } }) </script> <style> .comp-fade-enter-active, .comp-fade-leave-active {transition: opacity .3s ease;} .comp-fade-enter, .comp-fade-leave-to {opacity: 0;}/* .component-fade-leave-active for below version 2.1.8 */ </style>
列表过渡
<div id="list-demo" class="demo"> <button v-on:click="add">Add</button> <button v-on:click="remove">Remove</button> <transition-group name="list" tag="p"> <span v-for="item in items" v-bind:key="item" class="list-item">{{ item }}</span> </transition-group> </div> <script> new Vue({ el: '#list-demo', data: { items: [1,2,3,4,5,6,7,8,9], next: 10 }, computed:{ rIndex: function () { return Math.floor(Math.random() * this.items.length) }, }, methods: { add: function () { this.items.splice(this.rIndex, 0, this.next++) }, remove: function () { this.items.splice(this.rIndex, 1) }, } }) </script> <style> .list-item { display: inline-block; margin-right: 10px; display: inline-block; } .list-enter-active, .list-leave-active { transition: all 1s; } .list-enter, .list-leave-to { opacity: 0; transform: translateY(30px); } /* .list-leave-active for below version 2.1.8 */ .list-move { transition: transform 1s; } </style>
https://codesandbox.io/s/github/vuejs/vuejs.org/tree/master/src/v2/examples/vue-20-list-move-transitions?file=/index.html:0-1157
<!DOCTYPE html> <html> <head> <title>List Move Transitions Sudoku Example</title> <script src="https://unpkg.com/[email protected]"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script> <link rel="stylesheet" type="text/css" href="/style.css" /> </head> <body> <div id="sudoku-demo" class="demo"> <h1>Lazy Sudoku</h1> <p>Keep hitting the shuffle button until you win.</p> <button @click="shuffle">Shuffle</button> <transition-group name="cell" tag="div" class="container"> <div v-for="cell in cells" :key="cell.id" class="cell">{{ cell.number }}</div> </transition-group> </div> <script> new Vue({ el: "#sudoku-demo", data: { cells: Array.apply(null, { length: 81 }).map(function(_, index) { return { id: index, number: (index % 9) + 1 }; }) }, methods: { shuffle: function() { //创建一个被打乱值的集合 this.cells = _.shuffle(this.cells); } } }); </script> </body> </html>