Vue.js 3.0 学习笔记(十)过渡和动画效果

一、单元素/组件过渡

1、CSS过渡

控制p元素显示和隐藏

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>控制p元素显示和隐藏</title>
</head>
<body>
<div id="app">
    <button v-on:click="show = !show">
        上京即事五首·其一
    </button>
    <p v-if="!show">大野连山沙作堆,白沙平处见楼台。</p>
    <p v-if="!show">行人禁地避芳草,尽向曲阑斜路来。</p>
</div>
<!--引入vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
    //创建一个应用程序实例
    const vm= Vue.createApp({
        //该函数返回数据对象
        data(){
          return{
             show:true
           }
        }
        //在指定的DOM元素上装载应用程序实例的根组件
     }).mount('#app');
</script>
</body>
</html>

添加CSS过渡效果

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>添加CSS过渡效果</title>
</head>
<body>
<style>
       /*v-enter-active入场动画的时间段*/
       /*v-leave-active离场动画的时间段*/
       .v-enter-active, .v-leave-active{
            transition: all .5s ease;
        }
       /*v-enter:是一个时间点,进入之前,元素的起始状态,此时还没有进入*/
       /*v-leave-to:是一个时间点,是动画离开之后,离开的终止状态,此时元素动画已经结束。*/
       .v-enter, .v-leave-to{
            opacity: 0.2;
            transform:translateY(200px);
       }
</style>
<div id="app">
    <button v-on:click="show = !show">
        古诗欣赏
    </button>
    <transition>
        <p v-if="!show">鸿雁长飞光不度,鱼龙潜跃水成文。</p>
    </transition>
</div>

<!--引入vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
    //创建一个应用程序实例
    const vm= Vue.createApp({
        //该函数返回数据对象
        data(){
          return{
             show:true
           }
        }
        //在指定的DOM元素上装载应用程序实例的根组件
     }).mount('#app');
</script>
</body>
</html>

在这里插入图片描述
多个过渡效果

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>多个过渡效果</title>
</head>
<body>
<style>
        .v-enter-active, .v-leave-active {
            transition: all 0.5s ease;
        }
        .v-enter, .v-leave-to{
            opacity: 0.2;
            transform:translateX(150px);
        }
        .my-transition-enter-active, .my-transition-leave-active {
            transition: all 0.8s ease;
        }
        .my-transition-enter, .my-transition-leave-to{
            opacity: 0.2;
            transform:translateY(200px);
        }
    </style>
<div id="app">
    <button v-on:click="show = !show">
        出郊
    </button>
    <transition>
        <p v-if="!show">高田如楼梯,平田如棋局。</p>
    </transition>
    <transition name="my-transition">
        <p v-if="!show">白鹭忽飞来,点破秧针绿。</p>
    </transition>
</div>

<!--引入vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
    //创建一个应用程序实例
    const vm= Vue.createApp({
        //该函数返回数据对象
        data(){
          return{
             show:true
           }
        }
        //在指定的DOM元素上装载应用程序实例的根组件
     }).mount('#app');
</script>
</body>
</html>

3、CSS动画

和CSS过渡类似,只是v-enter类是在animationed事件触发时删除

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>CSS动画</title>
</head>
<body>
<style>
        /*进入动画阶段*/
        .my-enter-active {
            animation: my-in .5s;
        }
        /*离开动画阶段*/
        .my-leave-active {
            animation: my-in .5s reverse;
        }
        /*定义动画my-in*/
        @keyframes my-in {
            0% {
                transform: scale(0);
            }
            50% {
                transform: scale(1.5);
            }
            100% {
                transform: scale(1);
            }
        }
    </style>
<div id="app">
    <button @click="show = !show">对雪</button>
    <transition name="my">
        <p v-if="show">六出飞花入户时,坐看青竹变琼枝。如今好上高楼望,盖尽人间恶路岐。</p>
    </transition>
</div>

<!--引入vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
    //创建一个应用程序实例
    const vm= Vue.createApp({
        //该函数返回数据对象
        data(){
          return{
             show:true
           }
        }
        //在指定的DOM元素上装载应用程序实例的根组件
     }).mount('#app');
</script>
</body>
</html>

4、自定义过渡的类名

可以通过以下attribute来自定义过渡类名

  • enter-class
  • enter-active-class
  • enter-to-class
  • leave-class
  • leave-active-class
  • leave-to-class

attribute表示特性,其含义相当于v-bind,proterty则代表的是具体属性

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>自定义过渡的类名</title>
</head>
<body>
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
<div id="app">
    <button @click="show = !show">
        早春
    </button>
<!--    enter-active-class:控制动画的进入-->
<!--    leave-active-class:控制动画的离开-->
<!--animated 类似于全局变量,它定义了动画的持续时间;-->
<!--bounceInUp和slideInRight是动画具体的动画效果的名称,可以选择任意的效果。-->
    <transition
            enter-active-class="animated bounceInUp"
            leave-active-class="animated slideInRight"
    >
        <p v-if="show">春销不得处,唯有鬓边霜。</p>
    </transition>
</div>
<!--引入vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
    //创建一个应用程序实例
    const vm= Vue.createApp({
        //该函数返回数据对象
        data(){
          return{
             show:true
           }
        }
        //在指定的DOM元素上装载应用程序实例的根组件
     }).mount('#app');
</script>
</body>
</html>

5、动画的JavaScript钩子函数

听名字就知道是什么东东了
在< transition >组件中声明JavaScript钩子

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>JavaScript钩子函数</title>
</head>
<body>
<!--Velocity和jQuery.animate 的工作方式类似,也是用来实现JavaScript动画的一个很棒的选择-->
<script src="velocity.js"></script>
<div id="app">
    <button @click="show = !show">
        雪晴晚望
    </button>
    <transition
            v-on:before-enter="beforeEnter"
            v-on:enter="enter"
            v-on:leave="leave"
            v-bind:css="false"
    >
        <p v-if="show">
            野火烧冈草,断烟生石松。
        </p>
    </transition>
</div>
<!--引入vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
    //创建一个应用程序实例
    const vm= Vue.createApp({
        //该函数返回数据对象
        data(){
          return{
             show:false
           }
        },
        methods: {
            // 进入动画之前的样式
            beforeEnter: function (el) {
             // 注意:动画钩子函数的第一个参数:el,表示
             // 要执行动画的那个DOM元素,是个原生的 JS DOM 对象
             // 可以认为,el 是通过 document.getElementById('') 方式获取到的原生JS DOM对象
                el.style.opacity = 0;
                el.style.transformOrigin = 'left';
            },
            // 进入时的动画
            enter: function (el, done) {
                Velocity(el, { opacity: 1, fontSize: '2em' }, { duration: 300 });
                Velocity(el, { fontSize: '1em' }, { complete: done });
            },
            //离开时的动画
            leave: function (el, done) {
                Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 });
                Velocity(el, { rotateZ: '100deg' }, { loop: 5 });
                Velocity(el, {
                    rotateZ: '45deg',
                    translateY: '30px',
                    translateX: '30px',
                    opacity: 0
                }, { complete: done })
            }
        }
        //在指定的DOM元素上装载应用程序实例的根组件
     }).mount('#app');
</script>
</body>
</html>

二、初始渲染的过渡

通过appear属性设置节点在初始渲染的过渡效果

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>appear属性</title>
</head>
<body>
<style>
    .custom-appear{
        font-size: 50px;
        color: #c65ee2;
        background: #3d9de2;
    }
    .custom-appear-to{
        color: #e26346;
        background: #488913;
    }
    .custom-appear-active{
        color: red;
        background: #CEFFCE;
        transition: all 3s ease;
    }
</style>
<div id="app">
    <transition
            appear
            appear-class="custom-appear"
            appear-to-class="custom-appear-to"
            appear-active-class="custom-appear-active"
    >
        <p>野火烧冈草,断烟生石松。</p>
    </transition>
</div>
<!--引入vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
    //创建一个应用程序实例
    const vm= Vue.createApp({  }).mount('#app');
</script>
</body>
</html>

三、列表过渡

渲染整个列表使用< transition-group >组件

1、列表的进入/离开过渡

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>进入和离开的过渡效果</title>
</head>
<body>
<style>
        .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);
        }
    </style>
<div id="app" class="demo">
    <button v-on:click="add">添加</button>
    <button v-on:click="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>

<!--引入vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
    //创建一个应用程序实例
    const vm= Vue.createApp({
        //该函数返回数据对象
        data(){
          return{
            items: [10,20,30,40,50,60,70,80,90],
            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)
            }
        }
     //在指定的DOM元素上装载应用程序实例的根组件
     }).mount('#app');
</script>
</body>
</html>

2、列表的排序过渡

使用v-move class,它会在元素的改变定位过程中应用

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>列表的排序过渡</title>
</head>
<body>
<script src="lodash.js"></script>
<style>
    <!--v-move class -->
    .flip-list-move {
        transition: transform 1s;
    }
    </style>
<div id="app" class="demo">
    <button v-on:click="shuffle">排序过渡</button>
    <transition-group name="flip-list" tag="ul">
        <li v-for="item in items" v-bind:key="item">
            {{ item }}
        </li>
    </transition-group>
</div>

<!--引入vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
    //创建一个应用程序实例
    const vm= Vue.createApp({
        //该函数返回数据对象
        data(){
          return{
             items: [10,20,30,40,50,60,70,80,90],
            nextNum: 10
           }
        },
        methods: {
            shuffle: function () {
                //shuffle随机排序
                this.items = _.shuffle(this.items)
            }
        }
     //在指定的DOM元素上装载应用程序实例的根组件
     }).mount('#app');
</script>
</body>
</html>

3、交错过渡

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>列表的交错过渡</title>
</head>
<body>
<script src="velocity.js"></script>
<div id="app" class="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>
<!--引入vue文件-->
<script src="https://unpkg.com/vue@next"></script>
<script>
    //创建一个应用程序实例
    const vm= Vue.createApp({
        //该函数返回数据对象
        data(){
          return{
            query: '',
            list: [
                { msg: 'apple' },
                { msg: 'almond'},
                { msg: 'banana' },
                { msg: 'coconut' },
                { msg: 'date' },
                { msg: 'mango' },
                { msg: 'apricot'},
                { msg: 'banana' },
                { msg: 'bitter'}
            ]
           }
        },
        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)
            }
        }
     //在指定的DOM元素上装载应用程序实例的根组件
     }).mount('#app');
</script>
</body>
</html>

四、综合案例

1、商品编号增加器

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>商品编号增加器</title>
    <script src="https://unpkg.com/vue@next"></script>
    <style>
        .v-enter, .v-leave-to {
            opacity: 0;
        }
        .v-enter-active, .v-leave-active {
            transition: opacity 2s;
        }
    </style>
</head>
<body>
    <div id="app">
        <transition-group>
             <!-- 这里尽量不使用index作为key -->
            <div v-for="(item, index) of list" :key="item.id">
                {{item.title}}
            </div>
        </transition-group>
         <button @click="handleBtnClick">增加</button>
    </div>
    <script>
        var count = 0;
   //创建一个应用程序实例
    const vm= Vue.createApp({
        //该函数返回数据对象
        data(){
          return{
             list: []
            }
        } ,
         methods: {
            handleBtnClick () {
                this.list.push({
                    id:count++,
                    title: '商品编号:'+" "+ count
                })
            }
           }
     //在指定的DOM元素上装载应用程序实例的根组件
     }).mount('#app');
</script>
</body>
</html>

2、设计下拉菜单的过渡动画

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>过渡下拉菜单</title>
    <style type="text/css">
        #main {
            background-color:#CEFFCE;
            width: 300px;
        }
       #main ul{
            height: 9 rem;
            overflow-x: hidden;
         }
       .fade-enter-active, .fade-leave-active{
            transition: height 0.5s
        }
        .fade-enter, .fade-leave-to{
            height: 0
        }
    </style>
    <script src="https://unpkg.com/vue@next"></script>
</head>
<body>
    <div id="main">
        <button @click="test">主页</button>
        <transition name="fade">
            <ul v-if="show">
                <li>经典课程</li>
                      <ul>
                           <li><a href="#">Python开发课程</a></li>
                           <li><a href="#">Java开发课程</a></li>
                           <li><a href="#">网站前端开发课程</a></li>
                        </ul>
                <li>热门技术</li>
                      <ul>
                           <li><a href="#">前端开发技术</a></li>
                           <li><a href="#">网络安全技术</a></li>
                           <li><a href="#">PHP开发技术</a></li>
                        </ul>
                <li>畅销教材</li>
                      <ul>
                           <li><a href="#">网站前端开发教材</a></li>
                           <li><a href="#">C语言入门教材</a></li>
                           <li><a href="#">Python开发教材</a></li>
                        </ul>
                <li>联系我们</li>
            </ul>
        </transition>
    </div>
<script>
   //创建一个应用程序实例
    const vm= Vue.createApp({
        //该函数返回数据对象
        data(){
          return{
             show: false
            }
        } ,
         methods: {
              test () {
                    this.show = !this.show;
              }
            }
     //在指定的DOM元素上装载应用程序实例的根组件
     }).mount('#main');
</script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值