- A+
所属分类:Web前端
多个元素的过渡
我们之后讨论多个组件的过渡,对于原生标签可以使用 v-if/v-else。最常见的多标签过渡是一个列表和描述这个列表为空消息的元素:
<transition> <table v-if="items.length > 0"> <!-- ... --> </table> <p v-else>Sorry, no items found.</p> </transition>
可以这样使用,但是有一点需要注意:
当有相同标签名的元素切换时,需要通过 key attribute 设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。即使在技术上没有必要,给在 <transition> 组件中的多个元素设置 key 是一个更好的实践。
示例:
<transition> <button v-if="isEditing" key="save"> Save </button> <button v-else key="edit"> Edit </button> </transition>
在一些场景中,也可以通过给同一个元素的 key attribute 设置不同的状态来代替 v-if 和 v-else,上面的例子可以重写为:
<transition> <button v-bind:key="isEditing"> {{ isEditing ? 'Save' : 'Edit' }} </button> </transition>
使用多个 v-if 的多个元素的过渡可以重写为绑定了动态 property 的单个元素过渡。例如:
<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' } } }
完整案例:
<template> <div id="app"> <h1>home</h1> <!-- 当有相同标签名的元素切换时,需要通过 key attribute 设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。即使在技术上没有必要, 给在 <transition> 组件中的多个元素设置 key 是一个更好的实践。 --> <transition> <table v-if="items.length > 0"> table </table> <p v-else>Sorry, no items found.</p> </transition> <transition name="fade"> <button v-if="isEditing" key="save">Save</button> <button v-else key="edit">Edit</button> </transition> <transition name="fade"> <button v-bind:key="isEditing"> {{ isEditing ? "Save" : "Edit" }} </button> </transition> <transition name="fade"> <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> <br /> <transition name="fade"> <button v-bind:key="docState"> {{ buttonMessage }} </button> </transition> <br /> <br /> <button @click="change">改变</button> </div> </template> <script> export default { name: "home", data() { return { items: [], isEditing: true, docState: "saved", }; }, mounted() {}, components: {}, computed: { buttonMessage: function () { switch (this.docState) { case "saved": return "Edit"; case "edited": return "Save"; case "editing": return "Cancel"; } }, }, methods: { change() { this.items = [1, 2]; this.isEditing = !this.isEditing; this.docState = "edited"; }, }, }; </script> <style scoped> .fade-enter, .fade-leave-to { opacity: 0; transform: translateX(10px); } .fade-enter-active, .fade-leave-active { opacity: 1; transition: all 0.2s; } </style>