Vue2.X 过渡动画

本文详细介绍了在Vue2.x中如何实现过渡动画,包括给Vue控制的元素添加过渡动画、指定不同元素的过渡动画、保存过渡动画效果、使用第三方框架如Animate.css配合实现动画,以及在v-for中应用过渡动画,并解决过渡动画可能出现的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面: 此博客记录自己学习vue学习笔记,如有侵权,联系删!
学习来源: Vue + Vue-Cli 快速入门教程
李南江老师各平台账号:

  • 微博:极客江南
  • 微信公众号:李南江
  • 腾讯课堂: 李南江
  • 网易云课堂:李南江

给Vue控制的元素添加过渡动画

如何给Vue控制的元素添加过渡动画
1、将需要执行动画的元素放到transition组件中
2、当transition组件中的元素显示时会自动查找.v-enter.v-enter-active.v-enter-to类名
  当transition组件中的元素隐藏时会自动查找.v-leave.v-leave-active.v-leave-to类名
3、我们只需要在.v-enter.v-leave-to中指定动画动画开始的状态
  在.v-enter-active.v-leave-active中指定动画执行的状态
  即可完成过渡动画

html代码:

<div id="app">
    <button @click="toggle">我是按钮</button>
    <transition>
        <div class="box" v-show="isShow"></div>
    </transition>
</div>

vue代码:

// 这里就是MVVM中的View Model
let vue = new Vue({
    el: '#app',
    // 这里就是MVVM中的Model
    data: {
        isShow: false
    },
    // 专门用于存储监听事件回调函数
    methods: {
        toggle(){
            this.isShow = !this.isShow;
        }
    },
    // 专门用于定义计算属性的
    computed: {
    }
});

给多个不同元素指定不同过渡动画

transition注意点:
transition中只能放一个元素, 多个元素无效
如果想给多个元素添加过渡动画, 那么就必须创建多个transition组件

初始动画设置
默认情况下第一次进入的时候没没有动画的
如果想一进来就有动画, 我们可以通过给transition添加appear属性的方式
告诉Vue第一次进入就需要显示动画

如何给多个不同的元素指定不同的动画

  • 如果有多个不同的元素需要执行不同的过渡动画,那么我们可以通过给transition指定name的方式
    来指定"进入之前/进入之后/进入过程中, 离开之前/离开之后/离开过程中"对应的类名
  • 来实现不同的元素执行不同的过渡动画

html代码:

<div id="app">
    <button @click="toggle">我是按钮</button>
    <transition appear name="one">
        <div class="box" v-show="isShow"></div>
		<!--<div class="box" v-show="isShow"></div>-->
    </transition>
    <transition appear name="two">
        <div class="box" v-show="isShow"></div>
    </transition>
</div>

vue代码:

// 这里就是MVVM中的View Model
let vue = new Vue({
    el: '#app',
    // 这里就是MVVM中的Model
    data: {
    	isShow: true
    },
    // 专门用于存储监听事件回调函数
    methods: {
        toggle(){
            this.isShow = !this.isShow;
        }
    },
    // 专门用于定义计算属性的
    computed: {
    }
});

保存过渡动画最终的效果

当前过渡存在的问题
通过transition+类名的方式确实能够实现过渡效果
但是实现的过渡效果并不能保存动画之后的状态
因为Vue内部的实现是在过程中动态绑定类名, 过程完成之后删除类名
正式因为删除了类名, 所以不能保存最终的效果

在Vue中如何保存过渡最终的效果
通过Vue提供的JS钩子来实现过渡动画
v-on:before-enter="beforeEnter"进入动画之前
v-on:enter="enter"进入动画执行过程中
v-on:after-enter="afterEnter"进入动画完成之后
v-on:enter-cancelled="enterCancelled"进入动画被取消

v-on:before-leave="beforeLeave"离开动画之前
v-on:leave="leave"离开动画执行过程中
v-on:after-leave="afterLeave"离开动画完成之后
v-on:leave-cancelled="leaveCancelled"离开动画被取消

S钩子实现过渡注意点
1、在动画过程中必须写上el.offsetWidth或者el.offsetHeight
2、在enterleave方法中必须调用done方法, 否则after-enterafter-leave不会执行
3、需要需要添加初始动画, 那么需要把done方法包裹到setTimeout方法中调用

html代码:

<div id="app">
    <button @click="toggle">我是按钮</button>
    <!--
    注意点: 虽然我们是通过JS钩子函数来实现过渡动画
            但是默认Vue还是回去查找类名, 所以为了不让Vue去查找类名
            可以给transition添加v-bind:css="false"
    -->
    <transition appear
                v-bind:css="false"
                v-on:before-enter="beforeEnter"
                v-on:enter="enter"
                v-on:after-enter="afterEnter">
        <div class="box" v-show="isShow"></div>
    </transition>
</div>

vue代码:

// 这里就是MVVM中的View Model
let vue = new Vue({
    el: '#app',
    // 这里就是MVVM中的Model
    data: {
        isShow: true
    },
    // 专门用于存储监听事件回调函数
    methods: {
        toggle(){
            this.isShow = !this.isShow;
        },
        beforeEnter(el){
            // 进入动画开始之前
            console.log("beforeEnter");
            el.style.opacity = "0";
        },
        enter(el, done){
            // 进入动画执行过程中
            console.log("enter");
            /*
            注意点: 如果是通过JS钩子来实现过渡动画
                    那么必须在动画执行过程中的回调函数中写上
                    el.offsetWidth / el.offsetHeight
            * */
            // el.offsetWidth;
            el.offsetHeight;
            el.style.transition = "all 3s";
            /*
            注意点: 动画执行完毕之后一定要调用done回调函数
                    否则后续的afterEnter钩子函数不会被执行
            * */
            // done();
            /*
            注意点: 如果想让元素一进来就有动画, 那么最好延迟以下再调用done方法
            * */
            setTimeout(function () {
                done();
            }, 0);
        },
        afterEnter(el){
            // 进入动画执行完毕之后
            console.log("afterEnter");
            el.style.opacity = "1";
            el.style.marginLeft = "500px";
        }
    },
    // 专门用于定义计算属性的
    computed: {
    }
});

第三方框架实现过渡动画

配合Velocity实现过渡动画
在Vue中我们除了可以自己实现过渡动画以外, 还可以结合第三方框架实现过渡动画
步骤:
1、导入Velocity库
2、在动画执行过程钩子函数中编写Velocity动画

html代码:

<div id="app">
    <button @click="toggle">我是按钮</button>
    <transition appear
                v-bind:css="false"
                v-on:before-enter="beforeEnter"
                v-on:enter="enter"
                v-on:after-enter="afterEnter">
        <div class="box" v-show="isShow"></div>
    </transition>
</div>

vue代码:

<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<script>
	// 这里就是MVVM中的View Model
	let vue = new Vue({
	    el: '#app',
	    // 这里就是MVVM中的Model
	    data: {
	        isShow: true
	    },
	    // 专门用于存储监听事件回调函数
	    methods: {
	        toggle(){
	            this.isShow = !this.isShow;
	        },
	        beforeEnter(el){
	        },
	        enter(el, done){
	            Velocity(el, {opacity: 1, marginLeft: "500px"}, 3000);
	            done();
	        },
	        afterEnter(el){
	
	        }
	    },
	    // 专门用于定义计算属性的
	    computed: {
	    }
	});
</script>

自定义类名动画

.自定义类名动画
在Vue中
  除了可以使用 默认类名(v-xxx)来指定过渡动画
  除了可以使用 自定义类名前缀(yyy-xx)来指定过渡动画(transition name=“yyy”)
  除了可以使用 JS钩子函数来指定过渡动画以外
还可以使用自定义类名的方式来指定过渡动画

enter-class进入动画开始之前
enter-active-class进入动画执行过程中
enter-to-class进入动画执行完毕之后
leave-class离开动画开始之前
leave-active-class离开动画执行过程中
leave-to-class离开动画执行完毕之后

html代码:

<div id="app">
    <button @click="toggle">我是按钮</button>
    <transition appear
                enter-class="a"
                enter-active-class="c"
                enter-to-class="b">
        <div class="box" v-show="isShow"></div>
    </transition>
</div>

vue代码:

// 这里就是MVVM中的View Model
let vue = new Vue({
    el: '#app',
    // 这里就是MVVM中的Model
    data: {
        isShow: true
    },
    // 专门用于存储监听事件回调函数
    methods: {
        toggle(){
            this.isShow = !this.isShow;
        }
    },
    // 专门用于定义计算属性的
    computed: {
    }
});

配合Animate.css实现过渡动画

配合Animate.css实现过渡动画步骤:
1、导入Animate.css库
2、在执行过程中的属性上绑定需要的类名

css代码:

<style>
	*{
	    margin: 0;
	    padding: 0;
	}
	.box{
	    width: 200px;
	    height: 200px;
	    background: red;
	}
</style>
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">

html代码:

<div id="app">
    <button @click="toggle">我是按钮</button>
    <transition appear
                enter-class=""
                enter-active-class="animated bounceInRight"
                enter-to-class="">
        <div class="box" v-show="isShow"></div>
    </transition>
</div>

vue代码:

// 这里就是MVVM中的View Model
let vue = new Vue({
    el: '#app',
    // 这里就是MVVM中的Model
    data: {
        isShow: true
    },
    // 专门用于存储监听事件回调函数
    methods: {
        toggle(){
            this.isShow = !this.isShow;
        }
    },
    // 专门用于定义计算属性的
    computed: {
    }
});

v-for 在过渡动画中使用

v-for注意点
1、v-for为了提升性能, 在更新已渲染过的元素列表时,会采用“就地复用”策略。
  也正是因为这个策略, 在某些时刻会导致我们的数据混乱
  例如: 在列表前面新增了内容
2、为了解决这个问题, 我们可以在渲染列表的时候给每一个元素加上一个独一无二的key
  v-for在更新已经渲染过的元素列表时, 会先判断key是否相同, 如果相同则复用, 如果不同则重新创建

key属性注意点
不能使用index的作为key,因为当列表的内容新增或者删除时index都会发生变化

html代码:

<div id="app">
    <form>
        <input type="text" v-model="name">
        <input type="submit" value="添加" @click.prevent="add">
    </form>
    <ul>
	<!--<li v-for="(person,index) in persons" :key="person.id">-->
        <li v-for="(person,index) in persons" :key="index">
            <input type="checkbox">
            <span>{{index}} --- {{person.name}}</span>
        </li>
    </ul>
</div>

vue代码:

// 这里就是MVVM中的View Model
let vue = new Vue({
    el: '#app',
    // 这里就是MVVM中的Model
    data: {
        persons: [
            {name: "zs", id: 1},
            {name: "ls", id: 2},
            {name: "ww", id: 3}
            ],
        name: ""
    },
    // 专门用于存储监听事件回调函数
    methods: {
        add(){
            let lastPerson = this.persons[this.persons.length - 1];
            let newPerson = {name: this.name, id: lastPerson.id + 1};
            // this.persons.push(newPerson);
            this.persons.unshift(newPerson);
            this.name = "";
        }
    },
    // 专门用于定义计算属性的
    computed: {
    }
});

同时给多个元素添加过渡动画

如何同时给多个元素添加过渡动画
通过transition可以给单个元素添加过渡动画
如果想给多个元素添加过渡动画, 那么就必须通过transition-group来添加

transition-group和transition的用法一致, 只是一个是给单个元素添加动画, 一个是给多个元素添加动画而已

html代码:

<div id="app">
    <form>
        <input type="text" v-model="name">
        <input type="submit" value="添加" @click.prevent="add">
    </form>
    <ul>
        <transition-group appear>
        <li v-for="(person,index) in persons" :key="person.id" @click="del(index)">
            <input type="checkbox">
            <span>{{index}} --- {{person.name}}</span>
        </li>
        </transition-group>
    </ul>
</div>

vue代码:

// 这里就是MVVM中的View Model
let vue = new Vue({
    el: '#app',
    // 这里就是MVVM中的Model
    data: {
        persons: [
            {name: "zs", id: 1},
            {name: "ls", id: 2},
            {name: "ww", id: 3}
            ],
        name: ""
    },
    // 专门用于存储监听事件回调函数
    methods: {
        add(){
            let lastPerson = this.persons[this.persons.length - 1];
            let newPerson = {name: this.name, id: lastPerson.id + 1};
            // this.persons.push(newPerson);
            this.persons.unshift(newPerson);
            this.name = "";
        },
        del(index){
            this.persons.splice(index, 1);
        }
    },
    // 专门用于定义计算属性的
    computed: {
    }
});

解决过渡动画混乱

transition-group注意点:
默认情况下transition-group会将动画的元素放到span标签中
我们可以通过tag属性来指定将动画元素放到什么标签中

transition-group动画混乱问题
一般情况下组动画出现动画混乱都是因为v-for就地复用导致的
我们只需要保证所有数据key永远是唯一的即可

html代码:

<div id="app">
    <form>
        <input type="text" v-model="name">
        <input type="submit" value="添加" @click.prevent="add">
    </form>
	<!--<ul>-->
        <transition-group appear tag="ul">
        <li v-for="(person,index) in persons" :key="person.id" @click="del(index)">
            <input type="checkbox">
            <span>{{index}} --- {{person.name}}</span>
        </li>
        </transition-group>
	<!--</ul>-->
</div>

vue代码:

// 这里就是MVVM中的View Model
let vue = new Vue({
    el: '#app',
    // 这里就是MVVM中的Model
    data: {
        persons: [
            {name: "zs", id: 1},
            {name: "ls", id: 2},
            {name: "ww", id: 3}
            ],
        name: "",
        id: 3
    },
    // 专门用于存储监听事件回调函数
    methods: {
        add(){
            this.id++;
            // let lastPerson = this.persons[this.persons.length - 1];
            let newPerson = {name: this.name, id: this.id};
            // this.persons.push(newPerson);
            this.persons.unshift(newPerson);
            this.name = "";
        },
        del(index){
            this.persons.splice(index, 1);
        }
    },
    // 专门用于定义计算属性的
    computed: {
    }
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值