zoukankan      html  css  js  c++  java
  • 从零开始, 探索transition(vue-2.0)

    这里是官方文档:http://cn.vuejs.org/v2/guide/transitions.html

    一、开始
    结构如上一篇文章,我们在movie.vue中来写我们的第一个小过渡效果:

    在movie.vue写入:

    <template>
        <div id="movie">
            <button @click="showMenu" class="btn">{{text}}</button>
            <transition name="move">
                <div class="menu" v-show="show">
                    <div class="inner inner-1">1</div>
                </div>
            </transition>
        </div>
    </template>
    <script>
        export default {
            data() {
                return {
                    show: false
                };
            },
            methods: {
                showMenu() {
                    this.show = !this.show;
                }
            },
            computed: {
                text() {
                    return this.show ? '收' : '开';
                }
            }
        };
    </script>
    <style>
    #movie{
        margin-top:10px;
    }
    .btn{
        position: fixed;
        top:60px;
        left:50%;
        z-index:10;
        50px;
        height:50px;
        line-height:50px;
        border-radius: 50%;
        border:none;
        outline:none;
        color:#fff;
        font-size:18px;
        background:orange;
    }
    .inner-1{
        display: inline-block;
        position:absolute;
        30px;
        height:30px;
        line-height:30px;
        border-radius:50%;
        background: red;
        text-align:center;
        color:#fff;
        transition:all 0.4s;
        left:-50px;
        top:20px;
    }
    .menu{
        position:fixed;
        top:60px;
        left:50%;
        50px;
        height:50px;
        border-radius:50%;
        transition:all 0.7s linear;
    }
    /*上面主要都是样式代码*/
    .move-enter-active > .inner-1{
        transform: translate3d(0,0,0);
    }
    .move-enter > .inner-1,
    .move-leave-active >.inner-1{
        transition-timing-function: ease-in-out ;
        transform:translate3d(60px,0,0) ;
    }
    </style>

    再点开movie.vue,可以看到一个最简单的过渡效果:

    这里,我把enter为动画的起始状态,leave-active理解为返回最终状态(这个过渡效果类似CSS3的animation)

    其实也可以直接用CSS3的animation,只需要做如下修改

    <template>
        <div id="movie">
            <div id="example-2">
                <button @click="showMenu" class="btn">{{text}}</button>
                <transition name="bounce">
                    <p style="padding-left:50px" v-if="show">Look at me!</p>
    </transition>
    </div>
    </div>
    </template>
    <script>
        export default {
            data() {
                return {
                    show: false
                };
            },
            methods: {
                showMenu() {
                    this.show = !this.show;
                }
            },
            computed: {
                text() {
                    return this.show ? '逝' : '现';
                }
            }
        };
    </script>
    <style>
    #movie{
        margin-top:10px;
    }
    .btn{
        position: fixed;
        top:60px;
        left:50%;
        z-index:10;
        50px;
        height:50px;
        line-height:50px;
        border-radius: 50%;
        border:none;
        outline:none;
        color:#fff;
        font-size:18px;
        background:orange;
    }
    .bounce-enter-active {
      animation: bounce-in 2s;
    }
    .bounce-leave-active {
      animation: bounce-out 2s;
    }
    @keyframes bounce-in {
      0% {
        transform: scale(0);
      }
      50% {
        transform: scale(1.5);
      }
      100% {
        transform: scale(1);
      }
    }
    @keyframes bounce-out {
      0% {
        transform: scale(1);
      }
      50% {
        transform: scale(1.5);
      }
      100% {
        transform: scale(0);
      }
    }
    
    </style>

    运行

    其实就vue帮你加了个class又帮你移除了

    二、多个组件过渡

    组件的过渡可以痛通过绑定选中值实现

    这里我们再修改下movie.vue

    <template>
        <div id="movie">
            <div class="radio">
                <input type="radio" id="one" value="v-a" v-model="view">
                <label for="one">A</label>
                <input type="radio" id="two" value="v-b" v-model="view">
                <label for="two">B</label>
            </div>
            <div class="show">
                <transition name="component-fade" mode="out-in">
                    <component :is="view"></component>
                </transition>
            </div>
        </div>
    </template>
    <script>
        export default {
            data() {
                return {
                    view: 'v-a',
                    picked: 'one'
                };
            },
            components: {
                'v-a': {
                    template: '<div>Component A</div>'
                },
                'v-b': {
                    template: '<div>Component B</div>'
                }
            }
        };
    </script>
    <style>
    #movie{
        margin-top:25px;
        100%;
        height:200px;
        display:flex;
        flex-direction: column;
        align-items: center;
    }
    .component-fade-enter-active .conpoment-fade-leave-active{
        opacity: 1;
        transition: all 0.5s ease;
    }
    .component-fade-enter, .component-fade-leave-active {
      opacity: 0;
    }
    </style>

    这样我们就可以在选择的数据变化时实现简单的过渡:

    三、JavaScript 钩子

    script钩子其实就是一一设定绑定状态的变化,设置相对应的过渡效果,看下例子:

    html代码:

    <div id="movie">
            <img class="target" src="./basket.png"></img>
            <transition v-for="ball in balls" name="shooting" @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
                <!--外层做纵向动画-->
                <div class="ball" v-show="ball.show">
                    <!--内层做横向动画-->
                    <div class="inner"></div>
                </div>
            </transition>
            <img class="shoot" @click="shoot($event)" src="./player.png"></img>
        </div>

    script代码:

     data() {
                return {
                    balls: [
                        {
                            show: false
                        },
                        {
                            show: false
                        },
                        {
                            show: false
                        },
                        {
                            show: false
                        },
                        {
                            show: false
                        }
                    ],
                    dropBalls: []
                };
            },
            methods: {
                shoot(el) {
                    var balls = this.balls;
                    for (let i in balls) {
                        let ball = balls[i];
                        if (!ball.show) {
                            ball.show = true;
                            ball.el = el.target;
                            this.dropBalls.push(ball);
                            return;
                        }
                    }
                },
                beforeEnter:function(el) {
                    let count = this.balls.length;
                    while (count--) {
                        let ball = this.balls[count];
                        if (ball.show) {
                            let rect = ball.el.getBoundingClientRect();
                            let left = rect.left ;
                            console.log(el);
                            let top = -(window.innerHeight - rect.top - 520);
                            el.style.display = '';
                            el.style.webkitTransform = `translate3d(0,${top}px,0)`;
                            el.style.transform = `translate3d(0,${top}px,0)`;
                            let inner = el.getElementsByClassName('inner')[0];
                            inner.style.webkitTransform = `translate3d(${left}px,0,0)`;
                            inner.style.transform = `translate3d(${left}px,0,0)`;
                        }
                    }
                },
                enter:function(el) {
                    /* eslint-disable no-unused-vars */
                    let refresh = el.offsetHeight;
                    this.$nextTick(() => {
                        el.style.webkitTransform = 'translate3d(0,0,0)';
                        el.style.transform = 'translate3d(0,0,0)';
                        let inner = el.getElementsByClassName('inner')[0];
                        inner.style.webkitTransform = 'translate3d(0,0,0)';
                        inner.style.transform = 'translate3d(0,0,0)';
                    });
                },
                afterEnter:function(el) {
                    let ball = this.dropBalls.shift();
                    if (ball) {
                        ball.show = false;
                        el.style.display = 'none';
                    }
                }
            }

    其实就是设置相应的变化位置,完成变化,最后看下效果:

     

    四、表单过渡(transition-group)

    其实这个transition-group相当于给每一个元素添加一个transition,但需要指定唯一的标识key,看下代码:

    <template>
        <div id="movie">
            <div id="list-demo" class="demo">
                <button v-on:click="add">Add</button>
                <transition-group name="list" tag="ul">
                  // key值为item
                    <li v-for="(item,index) in items" :key="item" class="list-item" @click="deleteShow(index)">{{ item.text }}
    // 给删除按钮再加个动画
    <transition name="move"> <button class="deleteButton" v-show="item.show" @click="deleteItem(index)">删除</button> </transition> </li> </transition-group> </div> </div> </template>

    看上面的代码,其实就是和普通的transition是差不多的,只需理解为给每一个元素添加一个transition就行了,再看看样式代码:<style>

    #movie{
        margin-top:25px;
        100%;
        height:200px;
        display:flex;
        flex-direction: column;
        justify-content: flex-start;
        align-items: center;
        position:relative;
    }
    button{
        left:50%;
        margin-left:-50px;
        position:relative;
    }
    .deleteButton {
        position:absolute;
        50px;
        height:30px;
        bottom:0;
        left:300px;
    }
    .list-item {
      position:relative;
      display: inline-block;
      300px;
      height:30px;
      margin:5px 40px;
      background:lightgrey;
      transition: all 0.5s linear;
    }
    /*进入的初始状态*/ .list
    -enter, .list-leave-active { opacity:0; transform: translateX(-300px); } /*列表平滑过渡*/
    /*离开的状态*/
    .list-leave-active { transform: translateX(-300px); position:absolute } .move-enter,.move-leave-active{ transform: translate3d(50px,0,0); opacity: 0; } .move-enter-active,.move-leave-active{ opacity: 1; transition: all 0.2s linear; } </style>

    看下结果,实现了一个最简单<transition-group>:

    最主要的是理解经历的状态以及状态的变化,添加相应的样式,就可以做出想要的效果了

  • 相关阅读:
    Building Java Projects with Gradle
    Vert.x简介
    Spring及Spring Boot 国内快速开发框架
    dip vs di vs ioc
    Tools (StExBar vs Cmder)which can switch to command line window on context menu in windows OS
    SSO的定义、原理、组件及应用
    ModSecurity is an open source, cross-platform web application firewall (WAF) module.
    TDD中测试替身学习总结
    Spring事务银行转账示例
    台式机(华硕主板)前面板音频接口(耳机和麦克风)均无声的解决办法
  • 原文地址:https://www.cnblogs.com/lastnigtic/p/6497671.html
Copyright © 2011-2022 走看看