美文网首页
Vue.js动画过渡

Vue.js动画过渡

作者: 94very | 来源:发表于2019-01-04 23:07 被阅读0次

    该页面内容均来自vue.js官网(https://cn.vuejs.org/v2/guide/transitions.html#可复用的过渡),是对个人理解的总结,仅用于学习。


1. 多组件的过渡

    过渡模式
    in-out: 新元素先进行过渡,完成之后当前元素过渡离开。
    out-in: 当前元素先进行过渡,完成之后新元素过渡进入。

如下(该例子来自 vue 官网上)

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
    <title>多个组件的过渡</title>
    <style media="screen">
      * {
        margin: 0;
        padding: 0;
      }
      .component-fade-enter-active, .component-fade-leave-active {
        transition: opacity 0.3s ease;
      }
      .component-fade-enter, .component-fade-leave-to {
        opacity: 0;
      }
    </style>
  </head>
  <body>
  <div id="app">
    <input type="radio" @click="handleClick" name="a" checked="checked"><label>A</label>
    <input type="radio" @click="handleClick" name="a"><label>B</label>
    <transition name="component-fade" mode="out-in">
      <component v-bind:is="view"></component>
    </transition>
  </div>
  <script>
      var vm = new Vue({
         el: "#app",
         data: {
           view: 'v-a'
         },
         components: {
           'v-a': {
             template: '<div>Component A</div>'
           },
           'v-b': {
             template: '<div>Component B</div>'
           }
         },
         methods: {
           handleClick: function () {
             this.view = this.view === 'v-a' ? 'v-b' : 'v-a'
           }
         }
      })
  </script>
  </body>
</html>

解释

1. 设置 v-enter-active (进入) 和 v-leave-active (退出) 状态动画 3s 透明度变化
2. 设置 v-enter(开始进入) 和 v-leave-to(退出结束) 透明度变为 0
3. input 中的 name 值相同时变为单选,checked 值为 checked 时,为默认被选值
4. mode 设置为 out-in,则之前元素先完成动画,新元素再完成动画
5. v-bind:is="view" 设置值为 view
6. this.view = this.view === 'v-a' ? 'v-b' : 'v-a' 两者之间切换


2. 列表的进入/离开过渡

如下(该例子来自 vue 官网上)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <title>列表的进入/离开过渡</title>
    <style type="text/css">
        .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);
        }
        span {
            font-family: KaiTi;
            font-weight: 600;
            color: #444;
            font-size: 18px;
            float: left;
            margin-left: 10px;
            list-style-type: none;
        }
    </style>
</head>
<body>
    <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>
    <script type="text/javascript">
        var vm = 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)
                }
            }
        })
    </script>
</body>
</html>

解释

1. v-enter(开始进入) 和 v-leave-to(退出结束) 时的状态为下面 30px 透明,即新添
   加的元素出现或删除的元素消失,会在列表下 30px 透明,由此时向上,并显示。
2. data 中是一个 9 个数的数组,下个数是第 10 个。
3. randomIndex 中产生 0~1 的随机数,之后乘以现在数组的长度,向下取整返回该值。
4. add 中向数组中 this.randomIndex() 的位置上添加新元素,删除为 0(即不删除),新元素值为 this.nextNum。
5. remove 中向数组中 this.randomIndex() 的位置上删除 1 个元素。


3. 列表的排序过渡

如下(该例子来自 vue 官网上)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
    <title>列表排序过渡</title>
    <style type="text/css">
        .flip-list-move {
            transition: transform 1s;
        }
        li {
            font-family: KaiTi;
            font-weight: 600;
            color: #444;
            font-size: 18px;
            float: left;
            margin-left: 18px;
            list-style-type: none;
        }
    </style>
</head>
<body>
    <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>
    <script type="text/javascript">
        var vm = 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)
                }
            }
        })
    </script>
</body>
</html>

解释

1. 引用了 lodash 的动画库。
2. v-move 设置了动画的整体属性,动画时间 1s。
3. shuffle 中 this.items = _.shuffle(this.items) 数组的顺序被打乱,_shuffle 是 lodash库中的动画。


4. 动画过渡

如下(该例子来自 vue 官网上)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
    <title>动画过渡&动画队列</title>
    <style type="text/css">
        .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;
        }
        span {
            font-size: 18px;
            color: #555;
            font-weight: bolder;
            font-family: KaiTi;
            margin-left: 5px;
        }
    </style>
</head>
<body>
    <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>
    <script type="text/javascript">
        var vm = 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)
                }
            }
        })
    </script>
</body>
</html>

解释

1. randomIndex,add,remove 列表的进入/离开过渡。
2. shuffle 列表的排序过渡。


5. 多维网格动画过渡

如下(该例子来自 vue 官网上)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
    <title>多维网格的动画过渡</title>
    <style type="text/css">
        .container {
            display: flex;
            flex-wrap: wrap;
            width: 238px;
            margin-top: 10px;
        }
        .cell {
            display: flex;
            justify-content: space-around;
            align-items: center;
            width: 25px;
            height: 25px;
            border: 1px solid #aaa;
            margin-right: -1px;
            margin-bottom: -1px;
        }
        .cell:nth-child(3n) {
            margin-right: 0;
        }
        .cell:nth-child(27n) {
            margin-bottom: 0;
        }
        .cells-move {
            transition: transform 1s;
        }
    </style>
</head>
<body>
    <div id="sudoku-demo" class="demo">
        <button @click="shuffle">
            shuffle
        </button>
        <transition-group name="cells" tag="div" class="container">
            <div v-for="cell in cells" :key="cell.id" class="cell">
                {{ cell.number }}
            </div>
        </transition-group> 
    </div>
    <script type="text/javascript">
        new Vue({
            el: '#sudoku-demo',
            data: {
                cells: Array.apply(null, { length: 81 })
                    .map(function (_, index) {
                        return {
                            id: index,
                            number: index % 9 +1 
                        }
                    })
            },
            methods: {
                shuffle: function () {
                    this.cells = _.shuffle(this.cells)
                }
            }
        })
    </script>
</body>
</html>

解释

1. cell.number 中 number: index % 9 + 1 对 index 取余加1。
2. Array.apply(null, { length: 81 }) 第一个参数是对象,第二个参数是数组,该数组中并没有赋值。
3. .map 方法按照原始数组元素顺序依次处理元素。


6. 列表的交错过渡

如下(该例子来自 vue 官网上)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
    <title>列表的交错过渡</title>
    <style type="text/css">
        li {
            font-size: 24px;
            color: #444;
        }
    </style>
</head>
<body>
    <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>
    <script type="text/javascript">
        var vm = 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 vim = this
                    return this.list.filter(function (item) {
                        return item.msg.toLowerCase().indexOf(vim.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)
                }
            }
        })
    </script>
</body>
</html>

解释

1. v-for='(item, index) in computedList' 列表中的元素取自 computedList 函数中。
2. this.list.filter 对 list 数组进行过滤。
3. item.msg.toLowerCase().indexOf(vim.query.toLowerCase()) !== -1
    toLowerCase() 将字符串转换为小写,indexOf 返回某个指定的字符串值在字符串中首次出现的位置,
    这里的意思是将数组中的值转换为小写字符串,和 input 中填写的字符串转换为小写对比查找。 
4. v-bind:data-index='index' 则每一个 li 标签中,存在一个 data-index 值,data-index 值会随
   着 li 标签在数组中的位置改变。
5. var delay = el.dataset.index * 150;将 li 标签的 data-index 值乘于 150 毫秒,作为定时器
   动画执行时间。
1-3-1.PNG
1-3-2.PNG


7. 动态过渡

如下(该例子来自 vue 官网上)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
    <title>动态过渡</title>
</head>
<body>
    <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:defore-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>
    <script type="text/javascript">
        var vm = 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 vim = this
                    Velocity(el,
                        { opacity: 1 },
                        {
                            duration: this.fadeInDuration,
                            complete: function () {
                                done()
                                if (!vim.stop) vim.show =  false
                            }
                        }
                    )
                },
                leave: function (el, done) {
                    var vim = this
                    Velocity(el,
                        { opacity: 0 },
                        {
                            duration: this.fadeOutDuration,
                            complete: function () {
                                done()
                                vim.show = true
                            }
                        }
                    )
                }
            }
        })
    </script>
</body>
</html>

相关文章

  • Vue.js 过渡动画

    1. css实现过度 transition 动画 css-transform动画 动态组件 上述动画,如果设置mo...

  • Vue.js动画过渡

    该页面内容均来自vue.js官网(https://cn.vuejs.org/v2/guide/transition...

  • JS中的动画事件和过渡事件

    动画事件 动画事件demo 过渡动画事件 过渡动画事件demo

  • CSS3过渡动画

    过渡动画 transition属性简介transition是网页上的过渡动画,变化的逐渐过渡效果,简称过渡动画!列...

  • 过渡与动画

    @(HTML5)[过渡, 动画] [TOC] 五、过渡与动画 过渡 transition-property:过渡属...

  • 动画core animation

    type 动画过渡类型subtype 动画过渡方向

  • Android过渡动画Scene and Transition(

    Android场景过渡——Scene and Transition(一) 场景过渡动画 场景过渡动画是指以动画的形...

  • 016 过渡及动画

    过渡与动画 一、过渡 1、过渡属性 二、动画 1、动画属性 2、动画体 v_hint:动画属性设置给指定选择器标签...

  • CSS3--动画

    特点 过渡和动画之间的相同点过渡和动画都是用来给元素添加动画的过渡和动画都是系统新增的一些属性过渡和动画都需要满足...

  • CSS3动画

    css3动画包括过渡,形变,动画 过渡transition: 指定过渡样式:transition-property...

网友评论

      本文标题:Vue.js动画过渡

      本文链接:https://www.haomeiwen.com/subject/estlrqtx.html