共计 4359 个字符,预计需要花费 11 分钟才能阅读完成。
单元素或组件的过渡
<style> | |
.fade-enter{ | |
color:red; | |
font-size:0em; | |
opacity: 0; | |
} | |
.fade-enter-active{transition:all 5.5s;} | |
.fade-enter-to{ | |
color:green; | |
font-size:2em; | |
opacity: 1; | |
} | |
.fade-leave{color:green;} | |
.fade-leave-active{transition:all 5.5s;} | |
.fade-leave-to{ | |
color:red; | |
font-size: 0em; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="app"> | |
<button v-on:click="show = !show">Toggle</button> | |
<transition name="fade"> | |
<p v-if="show">hello</p> | |
</transition> | |
</div> | |
</body> | |
<script> | |
var app = new Vue({ | |
el:'#app', | |
data:{show:true,}, | |
methods:{}}) | |
</script> |
当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理:
1. 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加 / 删除 CSS 类名。
2. 如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。
3. 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡 / 动画,DOM 操作 (插入 / 删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同)
CSS 过渡
.slide-fade-enter-active {transition: all .3s ease;} | |
.slide-fade-leave-active {transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0); | |
} | |
.slide-fade-enter, .slide-fade-leave-to | |
/* .slide-fade-leave-active for below version 2.1.8 */ {transform: translateX(10px); | |
opacity: 0; | |
} | |
<div id="app2"> | |
<button v-on:click="show = !show">Toggle</button> | |
<transition name="slide-fade"> | |
<p v-if="show">hello</p> | |
</transition> | |
</div> |
CSS 动画
.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); | |
} | |
} | |
<div id="app3"> | |
<button v-on:click="show = !show">Toggle</button> | |
<transition name="bounce"> | |
<p v-if="show">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus</p> | |
</transition> | |
</div> |
自定义过渡的类名
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css"> | |
<div id="example-3"> | |
<button @click="show = !show"> | |
Toggle render | |
</button> | |
<transition | |
name="custom-classes-transition" | |
enter-active-class="animated tada" | |
leave-active-class="animated bounceOutRight" | |
> | |
<p v-if="show">hello</p> | |
</transition> | |
</div> |
显性的过渡持续时间
<transition :duration="1000">...</transition>
<transition :duration="{enter: 500, leave: 800}">...</transition>
JavaScript 钩子
<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) {// ...} | |
} |
多个元素的过渡
对于原生标签可以使用 v-if/v-else。最常见的多标签过渡是一个列表和描述这个列表为空消息的元素
<div id="app"> | |
<button @click="show = !show">Toggle</button> | |
<transition> | |
<table v-if="items.length > 0"> | |
<tr v-for="(index,item) in items"> | |
<td>{{index}}</td> | |
<td>{{item}}</td> | |
</tr> | |
</table> | |
<p v-else> | |
Sorry, no items found | |
</p> | |
</transition> | |
</div> | |
<script> | |
var app = new Vue({ | |
el:'#app', | |
data:{ | |
show:true, | |
items:[1,2,3] | |
}, | |
methods:{}}) | |
</script> <div id="app"> | |
<button @click="show = !show">Toggle</button> | |
<transition> | |
<table v-if="items.length > 0"> | |
<tr v-for="(index,item) in items"> | |
<td>{{index}}</td> | |
<td>{{item}}</td> | |
</tr> | |
</table> | |
<p v-else> | |
Sorry, no items found | |
</p> | |
</transition> | |
</div> | |
<script> | |
var app = new Vue({ | |
el:'#app', | |
data:{ | |
show:true, | |
items:[1,2,3] | |
}, | |
methods:{}}) | |
</script> |
当 items 中没有内容的时候,
当有相同标签名的元素切换时,Vue 为了效率只会替换相同标签内部的内容,因此给在 <transition> 组件中的多个元素设置 key 是一个更好的实践
过渡模式
这个部分的代码如下:
.fade-enter{transform: scale(0); | |
} | |
.fade-enter-actice{transition: all 0.5s ease;} | |
.fade-enter-to{transform: scale(1); | |
} | |
.fade-leave{transform: scale(1); | |
} | |
.fade-leave-active{transition: all 0.5s ease;} | |
.fade-leave-to{transform: scale(0); | |
} | |
</style> | |
<div id="app"> | |
<button @click="show = !show">Toggle</button> | |
<transition name="fade" mode="out-in"> | |
<button key="vtn-on" v-if="show">on</button> | |
<button key="vtn-off" v-else>off</button> | |
</transition> | |
</div> |
多个组件的过渡
上述代码改为:
<div id="app"> | |
<button @click="toggleView">Toggle</button> | |
<div class="moveBox"> | |
<transition name="fade" mode="out-in"> | |
<component v-bind:is="view"></component> | |
</transition> | |
</div> | |
</div> | |
<script> | |
Vue.component('btn-on',{template:'<button>ON</button>'}) | |
Vue.component('btn-off',{template:'<button>OFF</button>'}) | |
var app = new Vue({ | |
el:'#app', | |
data:{view:'btn-on'}, | |
methods:{toggleView(){if(this.view ==="btn-on"){this.view = "btn-off";}else{this.view ="btn-on"} | |
} | |
} | |
}) | |
</script> |
列表过渡和动态过渡就看官方文档的 demo 啦
正文完