从零开始, 探索transition(vue-2.0)

Posted lastnigtic

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从零开始, 探索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;
    width: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;
    width: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%;
    width: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;
    width: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;
    width: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;
    width: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;
    width:50px;
    height:30px;
    bottom:0;
    left:300px;
}
.list-item {
  position:relative;
  display: inline-block;
  width: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>:

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

以上是关于从零开始, 探索transition(vue-2.0)的主要内容,如果未能解决你的问题,请参考以下文章

从零开始探索做软件产品logback配置文件

从零开始,零基础,一点一点探索vue-router(vue2.0)

从零开始的ESP8266探索(11)-定时任务调度器Ticker使用演示

从零开始学习MySQL调试跟踪

从零开始实现一个React:JSX和虚拟DOM

68前端 | 从零开始实现React:JSX和虚拟DOM