发布时间:2023-06-20 17:30
过渡:元素状态缓慢改变的过程
动画:一个元素运动的情况
先写一个动画样式
<style>
@keyframes leftToRight {
from {
transform: translateX(-100px);
}
to {
transform: translateX(0);
}
}
.animation {
animation: leftToRight 3s;
}
style>
然后点击按钮,消除类名或者重新展示类名来实现动画重复播放的效果。
const app = Vue.createApp({
data() {
return {
animate: {
animation: false
}
}
},
methods: {
handleClick() {
this.animate.animation = !this.animate.animation
}
},
template: `
hello world
`
})
app.mount(\"#root\")
现在要实现过渡效果,使得背景色三秒缓慢改变。
渐变样式:
<style>
.transition {
transition: 3s background-color ease;
}
.blue {
background: blue;
}
.green {
background: green;
}
style>
实现过渡效果:
const app = Vue.createApp({
data() {
return {
animate: {
transition: true,
blue: true,
green: false,
}
}
},
methods: {
handleClick() {
this.animate.blue = !this.animate.blue;
this.animate.green = !this.animate.green;
}
},
template: `
hello world
`
})
app.mount(\"#root\")
</script>
看代码就知道是如何展现的了,和正常的 css 其实差不多,融入了一些 vue 的语法而已。
就是把 class 的样式写在行内。现在只需要一个 transition 类。
<style>
.transition {
transition: 3s background-color ease;
}
style>
然后触发点击事件的时候,样式对象的值进行修改即可。
const app = Vue.createApp({
data() {
return {
styleObj: {
background: \"blue\"
}
}
},
methods: {
handleClick() {
if (this.styleObj.background === \"blue\") {
this.styleObj.background = \"green\"
} else {
this.styleObj.background = \"blue\"
}
}
},
template: `
hello world
`
})
vue 的 transition 可以很方便地实现入场出场过渡。
实现入场离开过渡所需要的条件:
v-if
)v-show
)实现过程:
<style>
.v-enter-from {
opacity: 0;
}
.v-enter-active {
transition: opacity 3s ease-out;
}
.v-enter-to {
opacity: 1;
}
.v-leave-from {
opacity: 1;
}
.v-leave-active {
transition: opacity 3s ease-out;
}
.v-leave-to {
opacity: 0;
}
style>
// js
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
}
},
template: `
hello world
`
})
app.mount(\"#root\")
上面的 css 写法可以继续优化,改成下面的形式:
<style>
.v-enter-from {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: opacity 3s ease-out;
}
.v-leave-to {
opacity: 0;
}
style>
原因在于,出场的最终状态的 opacity 肯定是 1 的。
和上面的实现方式是一样的,且写起来更简单。
<style>
@keyframes shake {
from {
transform: translateX(-100px);
}
to {
transform: translateX(50px);
}
}
.v-enter-active,
.v-leave-active {
animation: shake 3s;
}
style>
const app = Vue.createApp({
data() {
return {
show: false
}
},
methods: {
handleClick() {
this.show = !this.show;
}
},
template: `
hello world
`
})
app.mount(\"#root\")
上面的 v-enter-from, v-enter-active, v-enter-to 都是固定写法,但是如果有多个不同的过渡或动画效果起冲突了,那咋办?
这里就需要重新命名了,且重新命名可以增加可读性。
重命名就是在 transition 标签上填写 name 属性:
<transition name=\"fade\">
<p v-if=\"show\">hellop>
transition>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
我们可以通过以下 attribute 来自定义过渡类名,改完后,例如原本的入场时状态的类名是 v-enter-from,通过 enter-from-class 的类名定义后,入场时的状态类名就是自己定义的类名。
enter-from-class
enter-active-class
enter-to-class
leave-from-class
leave-active-class
leave-to-class
它们的优先级高于普通的类名,当希望将其它第三方 CSS 动画库与 Vue 的过渡系统相结合时十分有用,比如 Animate.css。
<link
href=\"https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.0/animate.min.css\"
rel=\"stylesheet\"
type=\"text/css\"
/>
<div id=\"demo\">
<button @click=\"show = !show\">
Toggle render
button>
<transition
name=\"custom-classes-transition\"
enter-active-class=\"animate__animated animate__tada\"
leave-active-class=\"animate__animated animate__bounceOutRight\"
>
<p v-if=\"show\">hellop>
transition>
div>
有时用的过渡效果是对的,但是持续时间有特定的要求,因此 transition 上可以指定持续时间。
<transition :duration=\"1000\">...transition>
你也可以分别指定进入和离开的持续时间:
<transition :duration=\"{ enter: 500, leave: 800 }\">...transition>
vue 文档里解释:
Vue 为了知道过渡何时完成,必须设置相应的事件监听器。它可以是 transitionend
或 animationend
,这取决于给元素应用的 CSS 规则。如果你只使用了其中一种,Vue 能自动识别其正确类型。
但是,在一些场景中,你需要给同一个元素同时设置两种过渡动效,比如有一个通过 Vue 触发的 CSS 动画,并且在悬停时结合一个 CSS 过渡。在这种情况中,你就需要使用 type
attribute 并设置 animation
或 transition
来显式声明你需要 Vue 监听的类型。
说的土一点,动画和过渡哪个占主体,例如持续时间由哪个为主,就让 type 设置为哪个。
也可以通过 js 实现动画效果,注意的是,css 实现动画效果需要通过属性名关闭。
<transition
@before-enter=\"beforeEnter\"
@enter=\"enter\"
@after-enter=\"afterEnter\"
@enter-cancelled=\"enterCancelled\"
@before-leave=\"beforeLeave\"
@leave=\"leave\"
@after-leave=\"afterLeave\"
@leave-cancelled=\"leaveCancelled\"
:css=\"false\"
>
transition>
// ...
methods: {
// --------
// 进入时
// --------
beforeEnter(el) {
// ...
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
enter(el, done) {
// ...
done()
},
afterEnter(el) {
// ...
},
enterCancelled(el) {
// ...
},
// --------
// 离开时
// --------
beforeLeave(el) {
// ...
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
leave(el, done) {
// ...
done()
},
afterLeave(el) {
// ...
},
// leaveCancelled 只用于 v-show 中
leaveCancelled(el) {
// ...
}
}
用 JS 来实现动画效果适用于那些用 JS 实现动画效果的 JS 库,自己正常使用的时候还是用 CSS 会好一些。
当只用 JavaScript 过渡的时候,在 enter
和 leave
钩子中必须使用 done
进行回调。否则,它们将被同步调用,过渡会立即完成。
多个单组件间可以通过 v-if
/v-else
来完成元素之间的过渡。
<transition>
<table v-if=\"items.length > 0\">
table>
<p v-else>Sorry, no items found.p>
transition>
但是有时候需要的是这个效果,原本的组件消失后,要展示的效果再展现,具有先后顺序,而不是消失和显示过渡效果同时进行。
这时需要时候过渡模式:
in-out
: 新元素先进行进入过渡,完成之后当前元素过渡离开。out-in
: 当前元素先进行离开过渡,完成之后新元素过渡进入。<transition name=\"fade\" mode=\"out-in\">
transition>
out-in
是最常用的过渡模式。
如果初次进入页面渲染的时候想要看到动画,添加
appear
属性名即可。
要实现点击按钮来进行渐变 hello 和 bye 的效果,代码如下,和上面的写法差不多,使用 v-if 和 v-else 组合。
<style>
.v-enter-from,
.v-leave-to {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: opacity 0.5s ease;
}
style>
const ComponentA = {
template: `hello world`
}
const ComponentB = {
template: `bye world`
}
const app = Vue.createApp({
data() {
return {
show: true
}
},
components: {
\"component-a\": ComponentA,
\"component-b\": ComponentB,
},
methods: {
handleClick() {
this.show = !this.show;
}
},
template: `
`
})
app.mount(\"#root\")
既然是组件切换了,使用动态组件切换也是可行的。
const app = Vue.createApp({
data() {
return {
component: \"component-a\"
}
},
components: {
\"component-a\": ComponentA,
\"component-b\": ComponentB,
},
methods: {
handleClick() {
this.component = this.component === \"component-a\" ? \"component-b\" : \"component-a\"
}
},
template: `
`
})
如果里边的列表要有过渡效果,使用 transition-group
包裹来实现动画效果。这样在列表添加删除的时候就会有相应的动画。除了常规的过渡效果使用的 class 以外,v-move
用来决定除了操作的列表项以外的其他的元素的动画效果。
<style>
.list-item {
/* inline 的元素要变成 inline-block,否则动画不显示 */
display: inline-block;
margin-right: 10px;
}
/* 新增的列表项的过渡效果 */
.v-enter-from {
opacity: 0;
transform: translateY(30px);
}
.v-enter-active {
transition: all 0.5s ease-in;
}
.v-ease-to {
opacity: 1;
transform: translateY(0px);
}
/* 其他列表项移动时的过渡效果 */
.v-move {
transition: all 0.5s ease-in;
}
style>
const app = Vue.createApp({
data() {
return {
list: [1, 2, 3]
}
},
methods: {
handleClick() {
this.list.unshift(this.list.length + 1)
}
},
template: `
{{ item }}
`
})
比如一个数,从 1 到 100,也可以有那种像汽车加油门的感觉,数字缓慢爬到 100,而非从 1 直接跳到 100。
如果要自己实现的话,这是如下代码:
const app = Vue.createApp({
data() {
return {
number: 1,
animateNumber: 1,
}
},
methods: {
handleClick() {
// 确定要增长到的数
this.number = 100
if (this.animateNumber < this.number) {
// 使用 setInterval 来促成渐变效果
const animation = setInterval(() => {
this.animateNumber += 1
if (this.animateNumber >= this.number) {
clearInterval(animation)
}
}, 10)
}
}
},
template: `
{{ animateNumber }}
`
})
美股数据获取 python_几行Python代码,轻松获取美股阿里巴巴的交易数据
【OpenCV 例程200篇】219. 添加数字水印(盲水印)
把一个人的特点写具体作文_五年级把一个人的特点写具体作文500字5篇
mysql 分页limit_MySQL中使用LIMIT进行分页的方法
记一次Windows10定时任务计划程序执行powershell脚本的问题
基于Win10+TensorRT+C++部署Siamese图像相似度网络实战篇
【JavaScript】巩固JS开发中十个常用功能/案例(11-20)(牛客题解)
【墨菲安全实验室】Spark(3.1.2, 3.2.1, 3.3.0版本)shell命令注入漏洞