多个元素的过渡

点击打开视频讲解更加详细

我们之后讨论多个组件的过渡,对于原生标签可以使用 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>

若对您有帮助,请点击跳转到B站一键三连哦!感谢支持!!!