Vue学习—深入剖析列表过渡

一、深入剖析列表过渡

1.过渡_列表过渡

当想要给一个列表添加过渡动效时,我们可以使用 <transition-group> 组件。

//App.vue
<template>
  <div id="app">
    <base-level >
      
    </base-level>
  </div>
</template>

<script>
import BaseLevel from './components/BaseLevel1';
export default {
    
    
  name: 'App',
  components: {
    
    
    BaseLevel
  },
}
</script>
//BaseLevel1
<template>
  <div class="demo">
    <button @click="show = !show">click</button>
    <transition-group>
      <div key="world" v-if="show">hello wrold</div>
      <div key="shanshan" v-if="show">hello shanshan</div>
    </transition-group>
  </div>
</template>

<script>
export default {
    
    
  data () {
    
    
    return {
    
    
      show: true
    }
  }
}
</script>

<style scoped>
.v-enter,
.v-leave-to {
    
    
  opacity: 0;
}

.v-enter-active,
.v-leave-active {
    
    
  transition: all .3s;
}

.v-leave,
.v-enter-to {
    
    
  opacity: 1;
}
</style>

在这里插入图片描述
在这里插入图片描述

该组件的特点:

  • 不同于 ,它会以一个真实元素呈现:默认为一个 。你也可以通过 tag attribute 更换为其他元素。
  • 过渡模式不可用,因为我们不再相互切换特有的元素。
  • 内部元素 总是需要 提供唯一的 key 属性值。
  • CSS 过渡的类将会应用在内部的元素中,而不是这个组/容器本身。
<template>
  <div class="demo">
    <button @click="handleAdd">添加</button>
    <button @click="handleRemove">移除</button>
    <button @click="handleShuffle">洗牌</button>

    <br />
    <transition-group tag="ul">//替换成ul
      <li
        v-for="item in lists"
        :key="item"
      >{
    
    {
    
     item }}</li>
    </transition-group>
  </div>
</template>

<script>
export default {
    
    
  data () {
    
    
    return {
    
    
      lists: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
      nextNum: 11,
    }
  },
  methods: {
    
    
    handleAdd () {
    
    
      const randomIndex = Math.floor( Math.random() * this.lists.length );
      this.lists.splice(randomIndex, 0, this.nextNum ++);
    },
    handleRemove () {
    
    
      const randomIndex = Math.floor( Math.random() * this.lists.length );
      this.lists.splice(randomIndex, 1);
    },
    handleShuffle () {
    
    
      this.lists.sort(() => Math.random() - 0.5);
    },
  },
}
</script>

在这里插入图片描述

2.列表的排序过渡

<transition-group> 组件提供了一个新的特性:v-move,它会在元素改变定位的过程中应用。
如何使用?通过类名即可设置:.v-move {}。
当给 <transition-group> 设置 name 特性时,例如name为fade,则 v-move 在使用时,需要替换为 fade-move。

注意:当移除一个列表元素时,需要将移除的元素脱离文档流,否则,要溢出的元素在移除过渡中一直处于文档流中,会影响到后面元素的move过渡效果。

内部的实现:Vue 使用了一个叫 FLIP 简单的动画队列,使用 transforms 将元素从之前的位置平滑过渡新的位置。

需要注意的是使用 FLIP 过渡的元素不能设置为 display: inline 。作为替代方案,可以设置为 display: inline-block 或者放置于 flex 中。

<template>
  <div class="demo">
    <button @click="handleAdd">添加</button>
    <button @click="handleRemove">移除</button>
    <button @click="handleShuffle">洗牌</button>

    <br />
    <transition-group tag="ul">
      <li
        v-for="item in lists"
        :key="item"
      >{
    
    {
    
     item }}</li>
    </transition-group>
  </div>
</template>

<script>
export default {
    
    
  data () {
    
    
    return {
    
    
      lists: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
      nextNum: 11,
    }
  },
  methods: {
    
    
    handleAdd () {
    
    
      const randomIndex = Math.floor( Math.random() * this.lists.length );
      this.lists.splice(randomIndex, 0, this.nextNum ++);
    },
    handleRemove () {
    
    
      const randomIndex = Math.floor( Math.random() * this.lists.length );
      this.lists.splice(randomIndex, 1);
    },
    handleShuffle () {
    
    
      this.lists.sort(() => Math.random() - 0.5);
    },
  },
}
</script>

<style scoped>
button {
    
    
  margin-bottom: 10px;
  margin-right: 10px;
}

ul,li {
    
    
  padding: 0;
  margin: 0;
}

li {
    
    
  list-style: none;
  display: inline-block;
  margin-right: 10px;
}

.v-enter,
.v-leave-to {
    
    
  opacity: 0;
  transform: translateY(30px);
}

.v-enter-active,
.v-leave-active {
    
    
  transition: all .3s;
}

.v-leave,
.v-enter-to {
    
    
  opacity: 1;
  transform: translateY(0px);
}

.v-move {
    
    
  transition: transform .3s; 
}
</style>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.列表的交错过渡

如果要给列表中的元素,应用更丰富的过渡效果,可以配合JavaScript钩子。

<template>
  <div class="demo">
    <input type="text" v-model="query">
    <transition-group tag="ul"
      @before-enter="beforeEnter"
      @enter="enter" @leave="leave">
      <li v-for="item in computedLists"
        :key="item.name">
        {
    
    {
    
     item.name }}
      </li>
    </transition-group>
    
  </div>
</template>

<script>
export default {
    
    
  data () {
    
    
    return {
    
    
      query: '',
      lists: [
        {
    
     name: 'shanshan'},
        {
    
     name: 'jicheng'},
        {
    
     name: 'chensitong'},
        {
    
     name: 'dengxuming'},
      ]
    }
  },
  computed: {
    
    
    computedLists () {
    
    
      return this.lists.filter(item => item.name.includes(this.query));//筛选包含输入字符的
    },
  },
  methods: {
    
    
    beforeEnter (el) {
    
    
      el.style.opacity = 0;
      el.style.height = 0;
    },
    enter (el, done) {
    
    
      Velocity(el, {
    
     opacity: 1, height: '24px' }, {
    
     duration: 300, complete: done })
    },
    leave (el, done) {
    
    
      Velocity(el, {
    
     opacity: 0, height: '0px' }, {
    
     duration: 300, complete: done })
    }
  },
}
</script>

<style scoped>
li {
    
    
  height: 24px;
}
</style>

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/xun__xing/article/details/108558458