• 多个元素的过渡
    • 过渡模式

    多个元素的过渡

    我们之后讨论多个组件的过渡,对于原生标签可以使用 v-if/v-else 。最常见的多标签过渡是一个列表和描述这个列表为空消息的元素:

    1. <transition>
    2. <table v-if="items.length > 0">
    3. <!-- ... -->
    4. </table>
    5. <p v-else>Sorry, no items found.</p>
    6. </transition>

    可以这样使用,但是有一点需要注意:

    当有相同标签名的元素切换时,需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。即使在技术上没有必要,给在 <transition> 组件中的多个元素设置 key 是一个更好的实践。

    示例:

    1. <transition>
    2. <button v-if="isEditing" key="save">
    3. Save
    4. </button>
    5. <button v-else key="edit">
    6. Edit
    7. </button>
    8. </transition>

    在一些场景中,也可以通过给同一个元素的 key 特性设置不同的状态来代替 v-ifv-else,上面的例子可以重写为:

    1. <transition>
    2. <button v-bind:key="isEditing">
    3. {{ isEditing ? 'Save' : 'Edit' }}
    4. </button>
    5. </transition>

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

    1. <transition>
    2. <button v-if="docState === 'saved'" key="saved">
    3. Edit
    4. </button>
    5. <button v-if="docState === 'edited'" key="edited">
    6. Save
    7. </button>
    8. <button v-if="docState === 'editing'" key="editing">
    9. Cancel
    10. </button>
    11. </transition>

    可以重写为:

    1. <transition>
    2. <button v-bind:key="docState">
    3. {{ buttonMessage }}
    4. </button>
    5. </transition>
    1. // ...
    2. computed: {
    3. buttonMessage: function () {
    4. switch (this.docState) {
    5. case 'saved': return 'Edit'
    6. case 'edited': return 'Save'
    7. case 'editing': return 'Cancel'
    8. }
    9. }
    10. }

    过渡模式

    这里还有一个问题,试着点击下面的按钮:

    多个元素的过渡 - 图1

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

    在元素绝对定位在彼此之上的时候运行正常:

    多个元素的过渡 - 图2

    然后,我们加上 translate 让它们运动像滑动过渡:

    多个元素的过渡 - 图3

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

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

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

    out-in 重写之前的开关按钮过渡:

    1. <transition name="fade" mode="out-in">
    2. <!-- ... the buttons ... -->
    3. </transition>

    多个元素的过渡 - 图4

    只用添加一个简单的特性,就解决了之前的过渡问题而无需任何额外的代码。

    in-out 模式不是经常用到,但对于一些稍微不同的过渡效果还是有用的。将之前滑动淡出的例子结合:

    多个元素的过渡 - 图5

    很酷吧?