Vue中多个元素或组件的过渡
多个元素的过渡
对于原生标签可以使用 v-if
/v-else实现多个元素之间的过渡,如下面代码:
.v-enter, .v-leave-to{ opacity: 0; } .v-enter-active, .v-leave-active{ transition: opacity 3s; } <div id="root"> <transition > <div v-if="show">hello world</div> <div v-else>bye world</div> </transition> <button @click="handleClick">toggle</button> </div> let vm = new Vue({ el: '#root', data: { show: true }, methods: { handleClick() { this.show = !this.show } } })
这样写会发现并没有显示动画效果,因为 Vue 在两个元素进行切换的时候,会尽量复用dom,就是因为这个原因,导致现在动画效果不会出现。
解决方案:当有相同标签名的元素切换时,需要通过 key
attribute 设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。
<div v-if="show" key="hello">hello world</div> <div v-else key="bye">bye world</div>
过渡模式
由于同时生效的进入和离开的过渡不能满足所有要求,所以 Vue 提供了过渡模式:
-
in-out
:新元素先进行过渡,完成之后当前元素过渡离开。(通俗理解就是 要显示的元素先显示,隐藏的元素再隐藏) -
out-in
:当前元素先进行过渡,完成之后新元素过渡进入。(通俗理解就是 要隐藏的元素先隐藏,显示的元素再显示)
可以使用过渡模式来实现多个元素切换时的效果
多个组件的过渡
多个组件的过渡简单很多 ——不需要使用 key
attribute。
先用普通的方式来实现切换:
.v-enter, .v-leave-to{ opacity: 0; } .v-enter-active, .v-leave-active{ transition: opacity 1s; } <div id="root"> <transition mode="in-out"> <child-one v-if="show"></child-one> <child-two v-else></child-two> </transition> <button @click="handleClick">切换</button> </div> Vue.component('child-one',{ template:'<div>child-one</div>' }) Vue.component('child-two',{ template:'<div>child-two</div>' }) let vm = new Vue({ el: '#root', data: { show: true }, methods: { handleClick() { this.show = !this.show } } })
也可以使用动态组件:
.v-enter, .v-leave-to { opacity: 0; } .v-enter-active, .v-leave-active { transition: opacity 1s; } <div id="root"> <transition mode="out-in"> <component :is="type"></component> </transition> <button @click="handleClick">toggle</button> </div> <script> Vue.component('child-one', { template: '<div>child-one</div>' }) Vue.component('child-two', { template: '<div>child-two</div>' }) var vm = new Vue({ el: "#root", data: { type: 'child-one' }, methods: { handleClick: function() { this.type = this.type === 'child-one' ? 'child-two' : 'child-one' } } }) </script>