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
这个apijs动画主要就是给
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>