Vue中多元素过渡特效的解决方案

最常见的多标签过渡是一个列表和描述这个列表为空消息的元素:

<transition> <table v-if="items.length > 0"> <!-- ... --> </table> <p v-else>Sorry, no items found.</p> </transition>

下面是一个例子

<style> .fade-enter,.fade-leave-to{opacity:0;} .fade-enter-active,.fade-leave-active{transition:opacity .5s;} </style> <div> <button @click="clear">清空数据</button> <button @click="reset">重置</button> <transition> <ul v-if="items.length > 0"> <li v-for="item in items">{{item}}</li> </ul> <p v-else>Sorry, no items found.</p> </transition> </div> <script> new Vue({ el: '#demo', data: { items: ['html','css','js'] }, methods:{ clear(){ this.items.splice(0); }, reset(){ history.go(); } } }) </script>

同标签名称

如果是相同标签名的元素切换时,Vue 为了效率只会替换相同标签内部的内容

<style> .fade-enter,.fade-leave-to{opacity:0;} .fade-enter-active,.fade-leave-active{transition:opacity .5s;} </style> <div> <button @click="show = !show">toggle</button> <transition> <p v-if="show">Jb51</p> <p v-else>JB51</p> </transition> </div> <script> new Vue({ el: '#demo', data: { show:true }, }) </script>

由下面的示例可知,两个相同的p元素切换时,无过渡效果

因此,对于具有相同标签名的元素切换的情况,需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们 

<div> <button @click="show = !show">toggle</button> <transition> <p v-if="show" key="trueMatch">Jb51</p> <p v-else key="falseMatch">JB51</p> </transition> </div>

替代if

在一些场景中,可以给通过给同一个元素的 key 特性设置不同的状态来代替 v-if 和 v-else

<transition> <button v-if="isEditing" key="save">Save</button> <button v-else key="edit">Edit</button> </transition>

上面的例子可以重写为

<transition> <button v-bind:key="isEditing"> {{ isEditing ? 'Save' : 'Edit' }} </button> </transition>

下面是一个例子

<style> .fade-enter,.fade-leave-to{opacity:0;} .fade-enter-active,.fade-leave-active{transition:opacity .5s;} </style> <div> <button @click="isEditing = !isEditing">toggle</button> <transition> <p v-bind:key="isEditing"> {{ isEditing ? 'Save' : 'Edit' }} </p> </transition> </div> <script> new Vue({ el: '#demo', data: { isEditing:true }, }) </script>

使用多个 v-if 的多个元素的过渡可以重写为绑定了动态属性的单个元素过渡

<transition> <button v-if="docState === 'saved'" key="saved">Edit</button> <button v-if="docState === 'edited'" key="edited">Save</button> <button v-if="docState === 'editing'" key="editing">Cancel</button> </transition>

可以重写为

<transition> <button v-bind:key="docState">{{ buttonMessage }}</button> </transition> computed: { buttonMessage: function () { switch (this.docState) { case 'saved': return 'Edit' case 'edited': return 'Save' case 'editing': return 'Cancel' } } }

下面是一个例子

<style> .fade-enter,.fade-leave-to{opacity:0;} .fade-enter-active,.fade-leave-active{transition:opacity .5s;} </style> <div> <button @click="change">change</button> <transition> <p v-bind:key="docState">{{ message }}</p> </transition> </div> <script> new Vue({ el: '#demo', data: { index:0, isEditing:true, arr:['saved','edited','editing'] }, computed: { docState(){ return this.arr[this.index]; }, message() { switch (this.docState) { case 'saved': return 'Edit' case 'edited': return 'Save' case 'editing': return 'Cancel' } } }, methods:{ change(){ this.index = (++this.index)%3; } } }) </script>

过渡模式

先看下面这个例子

<style> .fade-enter,.fade-leave-to{opacity:0;} .fade-enter-active,.fade-leave-active{transition:opacity .5s;} </style> <div> <transition> <button :key="isOn" @click="isOn = !isOn">{{ isOn ? 'On' : 'Off' }}</button> </transition> </div> <script> new Vue({ el: '#demo', data: { isOn: true }, }) </script>

在 “on” 按钮和 “off” 按钮的过渡中,两个按钮都被重绘了,一个离开过渡的时候另一个开始进入过渡。这是 <transition> 的默认行为 - 进入和离开同时发生

同时生效的进入和离开的过渡不能满足所有要求,所以 Vue 提供了过渡模式

in-out: 新元素先进行过渡,完成之后当前元素过渡离开。

out-in: 当前元素先进行过渡,完成之后新元素过渡进入。

in-out

下面使用in-out来重写之前的开关按钮过渡

<div> <transition mode="in-out"> <button :key="isOn" @click="isOn = !isOn">{{ isOn ? 'On' : 'Off' }}</button> </transition> </div>

out-in

下面使用out-in来重写之前的开关按钮过渡

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/2c80f77797f64f5381c43bee50c315bd.html