Vue列表过渡

前面的话

  本文将详细介绍Vue列表过渡

概述

  前面分别介绍了单元素CSS过渡JS过渡,以及多元素过渡。如何同时渲染整个列表呢?在这种情景中,需要使用<transition-group>组件

【<transition-group>】

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

<transition-group name="list" tag="p">
    <!-- ... -->
  </transition-group>

普通过渡

  下面是一个添加和删除列表项的例子

<style>
.list-item {display: inline-block;margin-right: 10px;}
.list-enter-active, .list-leave-active {transition: all 1s;}
.list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);}
</style>
<div id="list-demo" class="demo">
  <button @click="add">Add</button>
  <button @click="remove">Remove</button>
  <transition-group name="list" tag="p">
    <span v-for="item in items" :key="item" class="list-item">{{item}}</span>
  </transition-group>
</div>
<script>
new Vue({
  el: ‘#list-demo‘,
  data: {
    items: [1,2,3,4,5,6,7,8,9],
    nextNum: 10
  },
  methods: {
    randomIndex() {
      return Math.floor(Math.random() * this.items.length)
    },
    add() {
      this.items.splice(this.randomIndex(), 0, this.nextNum++)
    },
    remove() {
      this.items.splice(this.randomIndex(), 1)
    },
  }
})
</script>

平滑过渡

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

【v-move】

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

  在上面代码中基础上,做出如下改进:

  1、增加.list-move的样式,使元素在进入时实现过渡效果

  2、在.list-leave-active中设置绝对定位,使元素在离开时实现过渡效果

<style>
.list-item {display: inline-block;margin-right: 10px;}
.list-move,.list-enter-active, .list-leave-active {transition: 1s;}
.list-leave-active{position:absolute;}
.list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);}
</style>

变换过渡

  下面接着利用move属性,进行变换过渡,即一个列表中的列表项既不增加也不减少,只是不断地变换其位置

<style>
.list-move{transition: transform 1s;}
</style>
<div id="list-demo" class="demo">
  <button @click="shuffle">shuffle</button>
  <transition-group name="list" tag="ul">
    <li v-for="item in items" :key="item">{{item}}</li>
  </transition-group>
</div>
<script>
new Vue({
  el: ‘#list-demo‘,
  data: {
    items: [1,2,3,4,5,6,7,8,9],
  },
  methods: {
    shuffle(){
      this.items = this.items.sort(()=>{return Math.random() - 0.5;})
    },
  }
})
</script>

  下面的效果看起来很神奇,内部的实现,Vue 使用了一个叫 FLIP 简单的动画队列,使用 transforms 将元素从之前的位置平滑过渡新的位置

  下面将进入离开的例子和这个技术结合, 使列表的一切变动都会有动画过渡

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

<style>
.list-item {display: inline-block;margin-right: 10px;}
.list-move,.list-enter-active, .list-leave-active {transition: 1s;}
.list-leave-active{position:absolute;}
.list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);}
</style>

  以上代码中,由于move、enter和leave都需要设置transition。因此,直接在元素上设置transition即可

<style>
.list-item {display: inline-block;margin-right: 10px;transition: 1s;}
.list-leave-active{position:absolute;}
.list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);}
</style>

  下面是完整代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.list-item {display: inline-block;margin-right: 10px;transition: 1s;}
.list-leave-active{position:absolute;}
.list-enter, .list-leave-to{opacity: 0;transform: translateY(30px);}
</style>
</head>
<body>
<div id="list-demo" class="demo">
  <button @click="shuffle">shuffle</button>
  <button @click="add">Add</button>
  <button @click="remove">Remove</button>
  <transition-group name="list" tag="p">
    <span v-for="item in items" :key="item" class="list-item">{{item}}</span>
  </transition-group>
</div>
<script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/vue.js"></script>
<script>
new Vue({
  el: ‘#list-demo‘,
  data: {
    items: [1,2,3,4,5,6,7,8,9],
    nextNum: 10
  },
  methods: {
    randomIndex() {
      return Math.floor(Math.random() * this.items.length)
    },
    add() {
      this.items.splice(this.randomIndex(), 0, this.nextNum++)
    },
    remove() {
      this.items.splice(this.randomIndex(), 1)
    },
    shuffle(){
      this.items = this.items.sort(()=>{return Math.random() - 0.5;})
    },
  }
})
</script>
</body>
</html>

多维列表

  FLIP 动画不仅可以实现单列过渡,多维网格的过渡也同样简单

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.container {width: 270px;margin-top: 10px;line-height:30px;text-align:center;}
.cell {display: inline-block;width: 30px;height: 30px;outline: 1px solid #aaa;}
.cell-move {transition:1s;}
</style>
</head>
<body>
<div id="list-demo" class="demo">
  <button @click="shuffle">shuffle</button>
  <transition-group name="cell" tag="div" class="container">
    <span v-for="cell in cells" :key="cell.id" class="cell">{{ cell.number }}</span>
  </transition-group>
</div>
<script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/vue.js"></script>
<script>
new Vue({
  el: ‘#list-demo‘,
   data: {
      cells: Array.apply(null, { length: 81 })
        .map(function (_, index) {
          return {
            id: index,
            number: index % 9 + 1
          }
        })
    },
  methods: {
    shuffle(){
      this.cells = this.cells.sort(()=>{return Math.random() - 0.5;})
    },
  }
})
</script>
</body>
</html>

渐进过渡

  通过 data 属性与 JavaScript 通信 ,就可以实现列表的渐进过渡

  下面是使用CSS过渡实现的一个例子

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.list-move,.list-enter-active, .list-leave-active {transition: 1s;}
.list-leave-active{position:absolute;}
.list-enter,.list-leave-to{opacity: 0;height:0;}
</style>
</head>
<body>
<div id="list-demo" class="demo">
  <input v-model="query">
  <transition-group name="list" tag="ul">
    <li v-for="(item, index) in computedList" :key="item" :data-index="index">{{item}}</li>
  </transition-group>
</div>
<script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/vue.js"></script>
<script>
new Vue({
  el: ‘#list-demo‘,
  data: {
    query: ‘‘,
    list: [‘HTML‘,‘CSS‘,‘Javascript‘,‘jQuery‘,‘Vue‘]
  },
  computed: {
    computedList() {
      return this.list.filter((item)=>{
        return item.toLowerCase().indexOf(this.query.toLowerCase()) !== -1
      })
    }
  },
})
</script>
</body>
</html>

  上面的效果中,列表项是一齐运动的。如果要实现依次运动的效果,则需要使用JS过渡来实现

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="list-demo" class="demo">
  <input v-model="query">
  <transition-group name="list" tag="ul" :css="false" @before-enter="beforeEnter" @enter="enter" @leave="leave">
    <li v-for="(item, index) in computedList" :key="item" :data-index="index">{{item}}</li>
  </transition-group>
</div>
<script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/velocity.min.js"></script>
<script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/26/ddzmgynp/vue.js"></script>
<script>
new Vue({
  el: ‘#list-demo‘,
  data: {
    query: ‘‘,
    list: [‘HTML‘,‘CSS‘,‘Javascript‘,‘jQuery‘,‘Vue‘]
  },
  computed: {
    computedList() {
      return this.list.filter((item)=>{
        return item.toLowerCase().indexOf(this.query.toLowerCase()) !== -1
      })
    }
  },
  methods: {
    beforeEnter(el) {
      el.style.opacity = el.style.height = 0
    },
    enter(el, done) {
      setTimeout(()=>{
        Velocity(el,{ opacity: 1, height: ‘1.6em‘ },{ complete: done })
      }, el.dataset.index * 150)
    },
    leave(el, done) {
      setTimeout(()=>{
        Velocity(el,{ opacity: 0, height: 0 },{ complete: done })
      }, el.dataset.index * 150)
    }
  },
})
</script>
</body>
</html>
时间: 2024-08-07 15:43:46

Vue列表过渡的相关文章

Vue学习笔记进阶篇——列表过渡及其他

本文为转载,原文:Vue学习笔记进阶篇--列表过渡及其他本文将介绍Vue中的列表过渡,动态过渡, 以及可复用过渡是实现. 列表过渡 目前为止,关于过渡我们已经讲到: 单个节点 同一时间渲染多个节点中的一个 那么怎么同时渲染整个列表,比如使用 v-for ?在这种场景中,使用 <transition-group>组件.在我们深入例子之前,先了解关于这个组件的几个特点: 不同于 <transition>, 它会以一个真实元素呈现:默认为一个<span>.你也可以通过 tag

Vue 列表动画实现

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" con

VUE:过渡&amp;动画

VUE:过渡&动画 vue动画的理解 1)操作css的 trasition 或 animation 2)vue会给目标元素添加/移除特定的class 3)过渡的相关类名 xxx-enter-active:指定显示的transition xxx-leave-active:指定隐藏的transition xxx-enter/xxx-leave-to:指定隐藏时的样式 <!DOCTYPE html> <html> <head> <meta charset=&qu

vue的过渡动画

在 vue 中往往需要添加动画,但是并不像 JQ 一样可以比较容易的添加,经常我会避免使用动画,这样就不用考虑了,但是在类似轮播图中,还是需要动画效果 动画样式 1234567891011121314 .slider-enter-active { transform: translateX(0); transition: all 1s ease;}.slider-leave-active { 大专栏  vue的过渡动画transform: translateX(-100%); transitio

Vue - 过渡 列表过渡

列表的进入/离开过渡 <div id="app" class="demo"> <button @click="add">Add</button> <button @click="remove">Remove</button> <br> <br> <transition-group name="list"> <

Vue.js 过渡 &amp; 动画

Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果. Vue 提供了内置的过渡封装组件,该组件用于包裹要实现过渡效果的组件. 首先是无过渡效果的动画 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>demo</title> <style> span._active{ background:pink; } <

Vue版本过渡变化

到了2.0以后,有哪些变化: 在每个组件模板,不在支持片段代码 之前: <template id="aaa"> <h3>我是组件</h3><strong>我是加粗标签</strong> </template> 现在:  必须有根元素,包裹住所有的代码 <template id="aaa"> <div> <h3>我是组件</h3> <stron

vue列表渲染

1. v-for 遍历数组 //item=>值,index=>索引 <ul id="example-2"> <li v-for="(item, index) in items"> {{ index }} - {{ item.message }} </li> </ul> var example2 = new Vue({ el: '#example-2', data: { items: [ { message:

Vue列表组件与弹窗组件示例

列表组件 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Page Title</title> <meta name="viewport" content=