1.前言
之前在公司上班 ,或者接私活 整体上动画其实几乎某用到
最近看文档 又梳理了下,那就记下来吧
2. transition
vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。包括以下工具:
1 .在 CSS 过渡和动画中自动应用 class
- 可以配合使用第三方 CSS 动画库,如 Animate.css 案例
- 在过渡钩子函数中使用 JavaScript 直接操作 DOM
- 可以配合使用第三方 JavaScript 动画库,如 Velocity.js
3.Vue 提供了 transition 的封装组件
动画的 钩子 生命周期可以看文档解释非常清除 ,这里简单说几个点
v-enter-active 简单理解为 标签出现的动画
v-leave-active 标签离开的动画
上面2个里面 一般定义 动画的时长 延迟和 曲线函数 就是那个贝塞尔曲线
例如 {animation: moveOne 1s;}
{transition: all 2s;}
v-enter-to 进入过渡的结束状态 比如出现后位置在哪颜色等
v-leave-to 离开过渡的结束状态 比如最后消失的位置 在哪
注意
v
就是transition
的name
属性对应的值
比如下面的案例name
是yzs
那么写 样式动画的时候 就用yzs
代替v
<template>
<div>
<button @click="show = !show">点击</button>
<!-- 在vue中提供了一个transition组件,让哪部分执行过渡动画,则使用transition包裹起来 -->
<transition name="yzs">
<div :class="styA" v-show="show">vue动画</div>
</transition>
</div>
</template>
<script>
export default {
data: function () {
return {
show: true,
styA: "classA",
};
},
};
</script>
<style lang="less" scoped>
.classA {
width: 200px;
height: 200px;
background-color: red;
font-size: 50px;
color: white;
text-align: center;
line-height: 200px;
}
/* 设置不同的进入和离开动画时的状态,设置了动画过渡时长 */
.yzs-enter-active,
.yzs-leave-active {
transition: all 2s;
}
/* .yzs-leave-to,.yzs-enter{
width: 50px;
height: 50px;
opacity: 0.2;
font-size: 16px;
transform: translate(500px,300px);
} */
/* 或者 */
.yzs-leave-to {
width: 50px;
height: 50px;
opacity: 0.2;
font-size: 16px;
transform: translate(0px, 0px);
}
.yzs-enter {
width: 80px;
height: 80px;
border-radius: 50%;
transform: translate(800px, 200px);
}
</style>
3.js动画
这里没有使用定时器 而是用了
requestAnimationFrame
这个api
js动画主要就是给vue
自带的钩子 绑定上自己的 动画函数就行
<template>
<div>
<input type="checkbox" v-model="show" />
<!-- transition还可以设置js动画,使用js设置动画时,需要监听transition组件的@leave事件,这个事件在元素需要做离场动画时调用。在事件绑定的函数中使用js进行动画 -->
<transition name="js-ani" @leave="leaveAniStart" @enter="enterAniStart">
<div id="box" v-show="show"></div>
</transition>
</div>
</template>
<script>
export default {
data: function () {
return {
show: true,
};
},
methods: {
// transtion组件的动画时间函数有两个参数,第一个是要做动画的元素。第二个是动画结束时的回调函数,必须在动画结束时调用。
leaveAniStart(el, callback) {
var opacity = 1;
function ani() {
opacity -= 0.02;
el.style.opacity = opacity;
if (opacity <= 0) {
callback();
} else {
requestAnimationFrame(ani);
}
}
requestAnimationFrame(ani);
},
enterAniStart(el, callback) {
var opacity = 0;
function ani() {
opacity += 0.02;
el.style.opacity = opacity;
if (opacity >= 1) {
callback();
} else {
requestAnimationFrame(ani);
}
}
requestAnimationFrame(ani);
},
},
};
</script>
<style lang="less" scoped>
#box {
width: 100px;
height: 100px;
background-color: red;
}
</style>
4.Velocity
4.1简介
Velocity 是一个简单易用、高性能、功能丰富的轻量级
JS
动画库。它能和jQuery
完美协作,并和$.animate()
有相同的API
, 但它不依赖jQuery
,可单独使用。Velocity
不仅包含了$.animate()
的全部功能, 还拥有:颜色动画、转换动画(transforms)、循环、 缓动、SVG 动画、和 滚动动画 等特色功能。
它比
$.animate()
更快更流畅,性能甚至高于CSS3 animation
, 是jQuery
和CSS3 transition
的最佳组合,它支持所有现代浏览器,最低可兼容到IE8
和Android 2.3
。
4.2 引入方式 1
直接脚本引入
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
4.3 脚手架项目
npm安装 注意 安装这个
velocity-animate
npm install velocity-animate -S
哪个组件使用哪个组件可以引入 ,
也可以作为全局引入
import Velocity from "velocity-animate";
4.4 使用方式都一样
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"
>
<div id="box" v-show="showView"></div>
</transition>
钩子
methods: {
beforeEnter (el) {
el.style.opacity = 0
},
enter (el, done) {
Velocity(el, { opacity: 1}, { duration: 3000,complete:done })
},
leave (el, done) {
Velocity(el, { opacity: 0}, { duration: 3000,complete:done })
}
}
比原生JS简单方便多了,可以多用用哦
5.列表动画
列表动画我觉得官网写的也挺好的 建议看看
注意key
值的写法 不要 用索引.因为索引永远不会变,不管你是插入,还是删除,第一个位置永远是0,第二个永远是1,监听不到key
的变化,自然也就无法做动画,其实就是底层diff
虚拟DOM
触发不了
<template>
<!-- 这个列表动画 官网写的挺好的 -->
<div>
<button @click="addClick">添加数字</button>
<div>
<!-- 对于列表的添加删除动画,必须使用transition-group标签 -->
<transition-group name="list" tag="ul">
<!-- 列表项参与动画时,必须有一个唯一的key属性
这里不建议使用 i ,因为用i作为,key的话,这个不会变化,
i是索引 不管怎么插入第一个位置索引永远是0,第二个位置索引永远是1,监听不到改变,不会进行动画
-->
<li v-for="(n, i) in arr" :key="n">{{ n }}</li>
</transition-group>
</div>
</div>
</template>
<script>
export default {
data: function () {
return {
arr: [1, 2, 3],
max: 4,
};
},
methods: {
addClick() {
var num = this.max++;
var index = Math.floor(Math.random() * (this.arr.length + 1));
this.arr.splice(index, 0, num);
},
},
};
</script>
<style lang="less" scoped>
li {
background-color: orange;
/* 如果列表中添加新元素时,其他元素“让位置”时也带动画,那么列表项元素必须设置transition过度,而且不能是inline元素 */
transition: all 0.7s;
width: 100px;
}
.list-enter {
transform: translate(-100%, 0);
}
.list-enter-active {
transition: all 0.7s;
}
.list-enter-to {
transform: translate(0, 0);
}
</style>