vue 列表过渡

目前为止,关于过渡我们已经讲到:

  • 单个节点
  • 同一时间渲染多个节点中的一个

那么怎么同时渲染整个列表,比如使用 v-for ?在这种场景中,使用 <transition-group> 组件。在我们深入例子之前,先了解关于这个组件的几个特点:

  • 不同于 <transition>,它会以一个真实元素呈现:默认为一个 <span>。你也可以通过 tag 特性更换为其他元素。
  • 内部元素 总是需要 提供唯一的 key 属性值

key的值应该和元素本身有关,而不是元素所在的位置,否则出现下面的问题,所有的添加和删除的过渡动画都是最后一个,因为只有最后一个元素的key改变了!!!!!

列表的进入/离开过渡

现在让我们由一个简单的例子深入,进入和离开的过渡使用之前一样的 CSS 类名。

<template>
  <div>
    <button v-on:click="add">Add</button>
    <button v-on:click="remove">Remove</button>
    <transition-group
      tag="p"
      mode="out-in"
      enter-active-class="animated fadeInUp"
      leave-active-class="animated fadeOutUp"
    >
    <span v-for="item in items" v-bind:key="item" class="list-item">
      {{ item }}
    </span>
    </transition-group>
  </div>
</template>

<script>
  export default {
    name: "a9",
    data() {
      return {
        items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
        nextNum: 10
      }
    },
    methods: {
      randomIndex: function () {
        return Math.floor(Math.random() * this.items.length)
      },
      add: function () {
        this.items.splice(this.randomIndex(), 0, this.nextNum++)
      },
      remove: function () {
        this.items.splice(this.randomIndex(), 1)
      },
    }
  }
</script>

<style scoped>
  .list-item {
    display: inline-block;
    margin-right: 10px;
  }

</style>

这个例子有个问题,当添加和移除元素的时候,周围的元素会瞬间移动到他们的新布局的位置,而不是平滑的过渡,我们下面会解决这个问题。

只需要加入v-move即可

<transition-group> 组件还有一个特殊之处。不仅可以进入和离开动画,还可以改变定位。要使用这个新功能只需了解新增的 v-move 特性,它会在元素的改变定位的过程中应用。像之前的类名一样,可以通过 name 属性来自定义前缀,也可以通过 move-class 属性手动设置。

  <transition-group
      tag="p"
      mode="out-in"
      move-class="move-class"
      enter-active-class="animated fadeInUp"
      leave-active-class="animated fadeOutUp"
    >

添加已经有了过渡效果,但是删除依然很僵硬,暂时没有找到办法

解决办法

必须在leave-active-class中设置绝对定位!!!!!!!!!!

<template>
  <div>
    <button v-on:click="add">Add</button>
    <button v-on:click="remove">Remove</button>
    <transition-group
      tag="p"
      mode="out-in"
      move-class="move-class"
      enter-active-class="animated fadeInUp"
      leave-active-class="animated fadeOutUp pos"
    >
    <span v-for="item in items" v-bind:key="item" class="list-item">
      {{ item }}
    </span>
    </transition-group>
  </div>
</template>

<script>
  export default {
    name: "a9",
    data() {
      return {
        items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
        nextNum: 10
      }
    },
    methods: {
      randomIndex: function () {
        return Math.floor(Math.random() * this.items.length)
      },
      add: function () {
        this.items.splice(this.randomIndex(), 0, this.nextNum++)
      },
      remove: function () {
        this.items.splice(this.randomIndex(), 1)
      },
    }
  }
</script>

<style scoped>
  .list-item {
    display: inline-block;
    margin-right: 10px;
  }
  .move-class{
    transition: 1s;
  }
  .pos{
    position: absolute;
  }
</style>

猜你喜欢

转载自my.oschina.net/ahaoboy/blog/1632557