详解Vue学习笔记进阶篇之列表过渡及其他


Posted in Javascript onJuly 17, 2017

本文将介绍Vue中的列表过渡,动态过渡, 以及可复用过渡是实现。

列表过渡

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

  1. 单个节点
  2. 同一时间渲染多个节点中的一个

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

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

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

<div id="app1">
  <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>
.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);
    }
var app1 = new Vue({
  el:'#app1',
  data:{
    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)
    }
  }
})

运行结果:

详解Vue学习笔记进阶篇之列表过渡及其他

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

列表的位移过渡

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

v-move对于设置过渡的切换时机和过渡曲线非常有用,你会看到如下的例子:

<div id="app2">
  <button @click="shuffle">Shuffle</button>
  <transition-group name="flip-list" tag="ul">
    <li v-for="item in items" :key="item">
      {{item}}
    </li>
  </transition-group>
</div>
.flip-list-move {
   transition: transform 1s;
}
var app2 = new Vue({
  el:'#app2',
  data:{
    items:[1,2,3,4,5,6,7,8,9]
  },
  methods:{
    shuffle:function () {
      this.items = _.shuffle(this.items)
    }
  }
})

这个例子需要添加以下引用

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>

运行结果:

详解Vue学习笔记进阶篇之列表过渡及其他

这个看起来很神奇,内部的实现,Vue 使用了一个叫 FLIP 简单的动画队列

使用 transforms 将元素从之前的位置平滑过渡新的位置。

我们将之前实现的例子和这个技术结合,使我们列表的一切变动都会有动画过渡。

<div id="app3" class="demo">
  <button @click="shuffle">Shuffle</button>
  <button @click="add">Add</button>
  <button @click="remove">Remove</button>
  <transition-group name="list-complete" tag="p">
    <span v-for="item in items" :key="item" class="list-complete-item">
      {{item}}
    </span>
  </transition-group>
</div>
.list-complete-item{
  transition: all 1s;
  display: inline-block;
  margin-right: 10px;
}
.list-complete-enter, .list-complete-leave-to{
  opacity: 0;
  transform: translateY(30px);
}
.list-complete-leave-active{
  position: absolute;
}
var app3 = new Vue({
  el:'#app3',
  data:{
    items:[1,2,3,4,5,6,7,8,9],
    nextNum:10
  },
  methods:{
    shuffle:function () {
      this.items = _.shuffle(this.items)
    },
    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)
    }
  }
})

运行结果:

详解Vue学习笔记进阶篇之列表过渡及其他

列表的渐进过渡

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

<div id="app4">
  <input v-model="query">
  <transition-group
    name="staggered-fade"
    tag="ul"
    :css="false"
    @before-enter="beforeEnter"
    @enter="enter"
    @leave="leave">
    <li v-for="(item, index) in computedList"
      :key="item.msg"
      :data-index="index">
      {{item.msg}}
    </li>
  </transition-group>
</div>
var app4 = new Vue({
  el:'#app4',
  data:{
    query:'',
    list:[
      {msg:'Bruce Lee'},
      {msg:'Jackie Chan'},
      {msg:'Chuck Norris'},
      {msg:'Jet Li'},
      {msg:'Kung Furry'},
      {msg:'Chain Zhang'},
      {msg:'Iris Zhao'},
    ]
  },
  computed:{
    computedList:function () {
      var vm = this
      return this.list.filter(function (item) {
        return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1
      })
    }
  },
  methods:{
    beforeEnter:function (el) {
      el.style.opacity = 0
      el.style.height = 0
    },
    enter:function (el, done) {
      var delay = el.dataset.index * 150
      setTimeout(function () {
        Velocity(el, {opacity:1, height:'1.6em'},{complete:done})
      }, delay)
    },
    leave:function (el, done) {
      var delay = el.dataset.index * 150
      setTimeout(function () {
        Velocity(el, {opacity:0, height:0}, {complete:done})
      }, delay)
    }
  }
})

上述js代码需要添加对Velocity引用:

<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>

运行结果如下:

详解Vue学习笔记进阶篇之列表过渡及其他

可复用的过渡

过渡可以通过 Vue 的组件系统实现复用。要创建一个可复用过渡组件,你需要做的就是将<transition>或者 <transition-group>作为根组件,然后将任何子组件放置在其中就可以了。

下面的例子是将上一个列表渐进过渡的例子改为可复用的过渡的源码:

<div id="app5">
  <input v-model="query">
  <my-transition :query="query" :list="list">
    <li v-for="(item, index) in computedList"
      :key="item.msg"
      :data-index="index">
      {{item.msg}}
    </li>
  </my-transition>
</div>
Vue.component('my-transition', {
  template:`
  <transition-group
    name="staggered-fade"
    tag="ul"
    :css="false"
    @before-enter="beforeEnter"
    @enter="enter"
    @leave="leave">
    <slot></slot>
  </transition-group>`,
  props:['query', 'list'],
  methods:{
    beforeEnter:function (el) {
      el.style.opacity = 0
      el.style.height = 0
    },
    enter:function (el, done) {
      var delay = el.dataset.index * 150
      setTimeout(function () {
        Velocity(el, {opacity:1, height:'1.6em'},{complete:done})
      }, delay)
    },
    leave:function (el, done) {
      var delay = el.dataset.index * 150
      setTimeout(function () {
        Velocity(el, {opacity:0, height:0}, {complete:done})
      }, delay)
    }
  }
})

var app5 = new Vue({
  el:'#app5',
  data:{
    query:'',
    list:[
      {msg:'Bruce Lee'},
      {msg:'Jackie Chan'},
      {msg:'Chuck Norris'},
      {msg:'Jet Li'},
      {msg:'Kung Furry'},
      {msg:'Chain Zhang'},
      {msg:'Iris Zhao'},
    ]
  },
  computed:{
    computedList:function () {
      var vm = this
      return this.list.filter(function (item) {
        return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1
      })
    }
  },
})

效果与上一个例子一致:

详解Vue学习笔记进阶篇之列表过渡及其他

但是函数组件更适合完成这个任务。由于暂时还没有学到render函数,所以暂时先不实现render函数组件。后面学到的时候再做打算。

动态过渡

在 Vue 中即使是过渡也是数据驱动的!动态过渡最基本的例子是通过 name 特性来绑定动态值。

<transition v-bind:name="transitionName">
 <!-- ... -->
</transition>

当你想用 Vue 的过渡系统来定义的 CSS 过渡/动画 在不同过渡间切换会非常有用。

所有的过渡特性都是动态绑定。它不仅是简单的特性,通过事件的钩子函数方法,可以在获取到相应上下文数据。这意味着,可以根据组件的状态通过 JavaScript 过渡设置不同的过渡效果。

<div id="app6">
  Fade In:
  <input type="range" v-model="fadeInDuration" min="0" :max="maxFadeDuration">
  Fade Out:
  <input type="range" v-model="fadeOutDuration" min="0" :max="maxFadeDuration">
  <transition
    v-bind:css="false"
    @before-enter="beforeEnter"
    @enter="enter"
    @leave="leave">
    <p v-if="show">hello chain</p>
  </transition>
  <button @click="stop = true">Stop it</button>
</div>
var app6 = new Vue({
  el: '#app6',
  data: {
    show: true,
    fadeInDuration: 1000,
    fadeOutDuration: 1000,
    maxFadeDuration: 1500,
    stop: false
  },
  mounted: function () {
    this.show = false
  },
  methods: {
    beforeEnter: function (el) {
      el.style.opacity = 0
    },
    enter: function (el, done) {
      var vm = this
      Velocity(el,
        { opacity: 1 },
        {
          duration: this.fadeInDuration,
          complete: function () {
            done()
            if (!vm.stop) vm.show = false
          }
        }
      )
    },
    leave: function (el, done) {
      var vm = this
      Velocity(el,
        { opacity: 0 },
        {
          duration: this.fadeOutDuration,
          complete: function () {
            done()
            vm.show = true
          }
        }
      )
    }
  }
})

运行结果:

详解Vue学习笔记进阶篇之列表过渡及其他

其中例子里的mounted是在Vue挂载完成,也就是模板中的html渲染到html页面中时的一个钩子函数,只会执行一次。具体内容可以理解下Vue的生命周期,这里就不赘述了。

但是如果这里不使用mounted的话,也是可以用初始渲染来实现,只不过比较麻烦。实现的方法是:

在transition中加入appear钩子函数:@appear="appear",然后在vue实例的methods中添加appear方法:

appear: function (el, done) {
      var vm = this
      Velocity(el,
        { opacity: 1 },
        {
          duration: this.fadeInDuration,
          complete: function () {
            done()
            if (!vm.stop) vm.show = false
          }
        }
      )
    }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript new fun的执行过程
Aug 05 Javascript
说明你的Javascript技术很烂的五个原因
Apr 26 Javascript
这段js代码得节约你多少时间
Dec 20 Javascript
JavaScript改变HTML元素的样式改变CSS及元素属性
Nov 12 Javascript
解决js图片加载时出现404的问题
Nov 30 Javascript
JQuery datepicker 用法详解
Dec 25 Javascript
浅析JS运动
Dec 28 Javascript
jQuery UI 实例讲解 - 日期选择器(Datepicker)
Sep 18 jQuery
关于vuejs中v-if和v-show的区别及v-show不起作用问题
Mar 26 Javascript
解决vue-cli单页面手机应用input点击手机端虚拟键盘弹出盖住input问题
Aug 25 Javascript
解决layui弹框失效的问题
Sep 09 Javascript
JavaScript原型式继承实现方法
Nov 06 Javascript
js学使用setTimeout实现轮循动画
Jul 17 #Javascript
详解Vue2.x-directive的学习笔记
Jul 17 #Javascript
javascript  数组排序与对象排序的实例
Jul 17 #Javascript
jQuery常用选择器详解
Jul 17 #jQuery
js轮播图的插件化封装详解
Jul 17 #Javascript
Vue.js中extend选项和delimiters选项的比较
Jul 17 #Javascript
Vue.js中组件中的slot实例详解
Jul 17 #Javascript
You might like
php指定函数参数默认值示例代码
2013/12/04 PHP
Thinkphp和onethink实现微信支付插件
2016/04/13 PHP
Laravel 中创建 Zip 压缩文件并提供下载的实现方法
2019/04/02 PHP
JavaScript 读取元素的CSS信息的代码
2010/02/07 Javascript
JS获取图片实际宽高及根据图片大小进行自适应
2013/08/11 Javascript
js判断选择时间不能小于当前时间的示例代码
2013/09/24 Javascript
JQuery实现级联下拉框效果实例讲解
2015/09/17 Javascript
jQuery插件开发精品教程(让你的jQuery更上一个台阶)
2015/11/07 Javascript
使用AJAX实现Web页面进度条的实例分享
2016/05/06 Javascript
JavaScript 基础函数_深入剖析变量和作用域
2016/05/18 Javascript
jQuery原理系列-常用Dom操作详解
2016/06/07 Javascript
jQuery基于toggle实现click触发DIV的显示与隐藏问题分析
2016/06/12 Javascript
AngularJS入门教程之REST和定制服务详解
2016/08/19 Javascript
js replace()去除代码中空格的实例
2017/02/14 Javascript
利用纯js + transition动画实现移动端web轮播图详解
2017/09/10 Javascript
Webpack框架核心概念(知识点整理)
2017/12/22 Javascript
基于react后端渲染模板引擎noox发布使用
2018/01/11 Javascript
angular6 利用 ngContentOutlet 实现组件位置交换(重排)
2018/11/02 Javascript
推荐一个基于Node.js的表单验证库
2019/02/15 Javascript
javascript实现倒计时关闭广告
2021/02/09 Javascript
Python脚本实时处理log文件的方法
2016/11/21 Python
Python图片裁剪实例代码(如头像裁剪)
2017/06/21 Python
python实现逐个读取txt字符并修改
2018/12/24 Python
讲解Python3中NumPy数组寻找特定元素下标的两种方法
2019/08/04 Python
Python一键安装全部依赖包的方法
2019/08/12 Python
python实现随机加减法生成器
2020/02/24 Python
利用 PyCharm 实现本地代码和远端的实时同步功能
2020/03/23 Python
如何使用 Flask 做一个评论系统
2020/11/27 Python
美国隐形眼镜零售商:LensPure
2019/03/10 全球购物
求职简历中的自我评价分享
2013/12/08 职场文书
农村婚庆司仪主持词
2014/03/15 职场文书
计算机求职信
2014/07/02 职场文书
酒店厨房管理制度
2015/08/06 职场文书
公安纪律作风整顿心得体会
2016/01/23 职场文书
使用CSS实现六边形的图片效果
2022/08/05 HTML / CSS
Python pyecharts案例超市4年数据可视化分析
2022/08/14 Python