三、多个元素、组件的过渡

1,多个元素的过渡

(1)对于原生标签我们可以使用 v-if/v-else 实现多元素过渡。下面是一个列表显示、数据空提示之间的过渡:

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

(2)如果有两个以上的元素过渡可以这么写:

注意:当有相同标签名的元素切换时,需要通过 key 特性设置唯一的值进行标记,从而让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。
<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>

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

<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'
    }
  }
}

2,过渡模式

(1)过渡模式常常配合多个元素或者多个组件切换时使用,有如下两种模式:

  • in-out:新元素先过渡过渡,完成之后当前元素过渡离开。(默认为该模式)
  • out-in:当前元素先过渡离开,离开完成后新元素过渡进入。
    (2)下面是一个元素组件切换样例,注意我这里将过渡模式设为(out-in):
  • 每次点击切换按钮后,下方“组件一”“组件二”会交替切换显示。
  • 切换时,当前组件会逐渐消失,等完全消失后新组件逐渐显示出来。

image.png

<template>
  <div id="app">
    <button @click="changeIndex">切换</button>
    <br>
    <transition name="fade" mode="out-in">
      <div id="div1" v-if="index === 1" key="div1">组件1</div>
      <div id="div2" v-else key="div2">组件2</div>
    </transition>
  </div>
</template>
 
<script>
export default {
  name: 'App',
  data: function(){
    return {
      index: 1, //显示的组件索引
    }
  },
  methods: {
    changeIndex() {
      this.index = (this.index%2)+1;
    }
  }
}
</script>
 
<style>
  #div1 {
    width:150px;
    height:100px;
    background:yellow;
  }
 
  #div2 {
    width:150px;
    height:100px;
    background:orange;
  }
 
  .fade-enter-active, .fade-leave-active{
    transition: all 0.5s ease
  }
 
  .fade-enter, .fade-leave-active {
    opacity: 0
  }
</style>

3,多个组件的过渡

(1)多个组件的过渡简单很多,我们不需要使用 key 特性,只需要使用动态组件即可。
(2)下面代码实现的功能效果同上面一样,只不过这次我们改用动态组件实现。

<template>
  <div id="app">
    <button @click="changeIndex">切换</button>
    <br>
    <transition name="fade" mode="out-in">
      <component :is="view"></component>
    </transition>
  </div>
</template>
 
<script>
export default {
  name: 'App',
  data: function(){
    return {
      index: 1, //显示的组件索引
      view: "v1"
    }
  },
  components: {
    'v1': {
      template: '<div style="width:150px;height:100px;background:yellow;">组件1</div>'
    },
    'v2': {
      template: '<div style="width:150px;height:100px;background:orange;">组件2</div>'
    }
  },
  methods: {
    changeIndex() {
      this.index = (this.index%2)+1;
      this.view = "v" + this.index;
    }
  }
}
</script>
 
<style>
  .fade-enter-active, .fade-leave-active{
    transition: all 0.5s ease
  }
 
  .fade-enter, .fade-leave-active {
    opacity: 0
  }
</style>

爱吃鸡蛋饼
55 声望8 粉丝