zoukankan      html  css  js  c++  java
  • vue 过渡效果-列表过渡

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

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

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

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

    列表的进入和离开过渡

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

    <div id="list-demo" class="demo">
    <button v-on:click="add">Add</button>
    <button v-on:click="remove">Remove</button>
    <transition-group name="list" tag="p">
    <span v-for="item in items" v-bind:key="item" class="list-item">
    {{ item }}
    </span>
    </transition-group>
    </div>
     
    new Vue({
    el: '#list-demo',
    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)
    },
    }
    })
     
    .list-item {
    display: inline-block;
    margin-right: 10px;
    }
    .list-enter-active, .list-leave-active {
    transition: all 1s;
    }
    .list-enter, .list-leave-to
    /* .list-leave-active for below version 2.1.8 */ {
    opacity: 0;
    transform: translateY(30px);
    }
    列表的位移过渡
    <transition-group>组件还有一个特殊之处。不仅可以进入和离开动画,还可以改变定位,要使用这个新功能只需了解新增的v-move特性,它会在元素改变定位的过程中应用。像之前的类名一样,可以通过name属性自定义前缀,也可以通过move-class属性手动设置。
    v-move对于设置过渡的切换时机和过渡曲线非常有用,你会看到如下的例子:
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
     
    <div id="flip-list-demo" class="demo">
    <button v-on:click="shuffle">Shuffle</button>
    <transition-group name="flip-list" tag="ul">
    <li v-for="item in items" v-bind:key="item">
    {{ item }}
    </li>
    </transition-group>
    </div>
     
    new Vue({
    el: '#flip-list-demo',
    data: {
    items: [1,2,3,4,5,6,7,8,9]
    },
    methods: {
    shuffle: function () {
    this.items = _.shuffle(this.items)
    }
    }
    })
     
    .flip-list-move {
    transition: transform 1s;
    }
     

    在内部的实现上,vue使用了一个叫flip简单的动画队列,使用transfrom将元素从之前的位置平滑过渡新的位置。

    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
     
    <div id="list-complete-demo" class="demo">
    <button v-on:click="shuffle">Shuffle</button>
    <button v-on:click="add">Add</button>
    <button v-on:click="remove">Remove</button>
    <transition-group name="list-complete" tag="p">
    <span
    v-for="item in items"
    v-bind:key="item"
    class="list-complete-item"
    >
    {{ item }}
    </span>
    </transition-group>
    </div>
    new Vue({
    el: '#list-complete-demo',
    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)
    },
    shuffle: function () {
    this.items = _.shuffle(this.items)
    }
    }
    })
     
    .list-complete-item {
    transition: all 1s;
    display: inline-block;
    margin-right: 10px;
    }
    .list-complete-enter, .list-complete-leave-to
    /* .list-complete-leave-active for below version 2.1.8 */ {
    opacity: 0;
    transform: translateY(30px);
    }
    .list-complete-leave-active {
    position: absolute;
    }
     
    需要注意的是使用flip过渡的元素不能设置为display:inline.作为替代方案,可以设置为display:inline-block或者放置与flex中。
    flip不仅可以实现单列过渡,多维网格的过渡也同样简单。
     
     
    列表的渐进过渡
    通过data属性与javascript通信,就可以实现列表的渐进过渡。
    <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
     
    <div id="staggered-list-demo">
    <input v-model="query">
    <transition-group
    name="staggered-fade"
    tag="ul"
    v-bind:css="false"
    v-on:before-enter="beforeEnter"
    v-on:enter="enter"
    v-on:leave="leave"
    >
    <li
    v-for="(item, index) in computedList"
    v-bind:key="item.msg"
    v-bind:data-index="index"
    >{{ item.msg }}</li>
    </transition-group>
    </div>
     
    new Vue({
    el: '#staggered-list-demo',
    data: {
    query: '',
    list: [
    { msg: 'Bruce Lee' },
    { msg: 'Jackie Chan' },
    { msg: 'Chuck Norris' },
    { msg: 'Jet Li' },
    { msg: 'Kung Fury' }
    ]
    },
    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)
    }
    }
    })
     
     
    可复用的过渡
    过渡可以通过vue的组件系统实现复用。要创建一个可复用的过渡组件,你需要做的就是将<transition>或<transition-group>作为根组件,然后将任何子组件放置其中就可以了。
    使用模板的简单例子:
    Vue.component('my-special-transition', {
    template: '
    <transition
    name="very-special-transition"
    mode="out-in"
    v-on:before-enter="beforeEnter"
    v-on:after-enter="afterEnter"
    >
    <slot></slot>
    </transition>
    ',
    methods: {
    beforeEnter: function (el) {
    // ...
    },
    afterEnter: function (el) {
    // ...
    }
    }
    })

    函数组件更适合完成这个任务:

    Vue.component('my-special-transition', {
    functional: true,
    render: function (createElement, context) {
    var data = {
    props: {
    name: 'very-special-transition',
    mode: 'out-in'
    },
    on: {
    beforeEnter: function (el) {
    // ...
    },
    afterEnter: function (el) {
    // ...
    }
    }
    }
    return createElement('transition', data, context.children)
    }
    })

    动态过渡

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

    <transition v-bind:name="transitionName">
    <!-- ... -->
    </transition>
    当你想用vue的过渡系统来定义的css过渡/动画在不同过渡间非常有用。
    所有的过渡特性都是动态绑定。它不仅是简单的特性,通过事件的钩子函数方法,可以在获取相应的上下文数据。这意味着,可以根据组件的状态通过javascript过渡设置不同的过渡效果。
    <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
     
    <div id="dynamic-fade-demo" class="demo">
    Fade In: <input type="range" v-model="fadeInDuration" min="0" v-bind:max="maxFadeDuration">
    Fade Out: <input type="range" v-model="fadeOutDuration" min="0" v-bind:max="maxFadeDuration">
    <transition
    v-bind:css="false"
    v-on:before-enter="beforeEnter"
    v-on:enter="enter"
    v-on:leave="leave"
    >
    <p v-if="show">hello</p>
    </transition>
    <button
    v-if="stop"
    v-on:click="stop = false; show = false"
    >Start animating</button>
    <button
    v-else
    v-on:click="stop = true"
    >Stop it!</button>
    </div>
     
    new Vue({
    el: '#dynamic-fade-demo',
    data: {
    show: true,
    fadeInDuration: 1000,
    fadeOutDuration: 1000,
    maxFadeDuration: 1500,
    stop: true
    },
    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
    }
    }
    )
    }
    }
    })
     
    最后,创建动态过渡的最终方案是组件通过接受props来动态修改之前的过渡。
  • 相关阅读:
    机器学习八
    机器学习七
    机器学习六
    机器学习五
    JMeter获取复杂的JSON串中的参数的值
    Jmeter返回参数值写入文件
    python 连接数据库
    jmeter返回的Unicode转换成utf8
    Appium与python自动测试环境及demo详解
    python解析复杂json字符串
  • 原文地址:https://www.cnblogs.com/susanws/p/7421857.html
Copyright © 2011-2022 走看看