- 【Vue3 从入门到实战 进阶式掌握完整知识体系】020-Vue
- 【Vue3 从入门到实战 进阶式掌握完整知识体系】007-Vue
- 【Vue3 从入门到实战 进阶式掌握完整知识体系】008-Vue
- 【Vue3 从入门到实战 进阶式掌握完整知识体系】005-Vue
- 【Vue3 从入门到实战 进阶式掌握完整知识体系】006-Vue
- 【Vue3 从入门到实战 进阶式掌握完整知识体系】009-Vue
- 【Vue3 从入门到实战 进阶式掌握完整知识体系】004-Vue
- 【Vue3 从入门到实战 进阶式掌握完整知识体系】002-Vue
- 【Vue3 从入门到实战 进阶式掌握完整知识体系】001-Vue
- 【Vue3 从入门到实战 进阶式掌握完整知识体系】003-Vue
2、使用 transition 标签实现单元素组件的过渡和动画效果
出入场动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 样式 -->
<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>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
show: false
}
},
methods:{
shift(){
this.show = !this.show;
}
},
template: `
<div>
<transition>
<div v-if="show">hello world!</div>
</transition>
<button @click="shift">切换</button>
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
运行结果
image-20210613214526364.png出入场动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 样式 -->
<style>
@keyframes shake {
0%{
transform: translateX(-100px);
}
50%{
transform: translateX(-50px);
}
100%{
transform: translateX(50px);
}
}
/* 入场动画 */
.v-enter-active {
animation: shake 3s;
}
/* 出场动画 */
.v-leave-active{
animation: shake 3s;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
show: false
}
},
methods:{
shift(){
this.show = !this.show;
}
},
template: `
<div>
<transition>
<div v-if="show">hello world!</div>
</transition>
<button @click="shift">切换</button>
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
运行结果
image-20210613220553678.png给transition加个name
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 样式 -->
<style>
@keyframes shake {
0%{
transform: translateX(-100px);
}
50%{
transform: translateX(-50px);
}
100%{
transform: translateX(50px);
}
}
/* 这里要以 hello 开头 */
/* 入场动画 */
.hello-enter-active {
animation: shake 3s;
}
/* 出场动画 */
.hello-leave-active{
animation: shake 3s;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
show: false
}
},
methods:{
shift(){
this.show = !this.show;
}
},
// 给 transition 设置 name='hello'
// 使用 v-show 同样能实现动画效果
template: `
<div>
<transition name='hello'>
<div v-if="show">hello world!</div>
</transition>
<button @click="shift">切换</button>
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
运行结果
image-20210613221046693.png在transition标签具体指定出入场动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 样式 -->
<style>
@keyframes shake {
0%{
transform: translateX(-100px);
}
50%{
transform: translateX(-50px);
}
100%{
transform: translateX(50px);
}
}
/* 这里要以 hello 开头 */
/* 入场动画 */
.hello {
animation: shake 3s;
}
/* 出场动画 */
.bye {
animation: shake 3s;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
show: false
}
},
methods:{
shift(){
this.show = !this.show;
}
},
template: `
<div>
<transition enter-active-class='hello' leave-active-class='bye'>
<div v-if="show">hello world!</div>
</transition>
<button @click="shift">切换</button>
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
运行结果
image-20210613222357389.png使用动画库Animate
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 引入Animate样式 cdn地址 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
show: false
}
},
methods:{
shift(){
this.show = !this.show;
}
},
template: `
<div>
<transition
enter-active-class='animate__animated animate__bounce'
leave-active-class='animate__animated animate__bounce'>
<div v-if="show">hello world!</div>
</transition>
<button @click="shift">切换</button>
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
运行结果
image-20210613223252594.png动画 + 过渡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 样式 -->
<style>
@keyframes shake {
0%{
transform: translateX(-100px);
}
50%{
transform: translateX(-50px);
}
100%{
transform: translateX(50px);
}
}
/* 入场动画 */
.v-enter-active {
animation: shake 3s;
transition: color 3s ease-in;
}
.v-enter-from{
color: red
}
/* 出场动画 */
.v-leave-active{
animation: shake 3s;
transition: color 3s ease-in;
}
.v-leave-from{
color: seagreen;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
show: false
}
},
methods:{
shift(){
this.show = !this.show;
}
},
template: `
<div>
<transition>
<div v-if="show">hello world!</div>
</transition>
<button @click="shift">切换</button>
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
运行结果
image-20210613225921555.png一个先执行完就是结束另一个
如果过渡执行完了就结束动画,反之亦然
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 样式 -->
<style>
@keyframes shake {
0%{
transform: translateX(-100px);
}
50%{
transform: translateX(-50px);
}
100%{
transform: translateX(50px);
}
}
/* 入场动画 */
.v-enter-active {
animation: shake 10s;
transition: color 3s ease-in;
}
.v-enter-from{
color: red
}
/* 出场动画 */
.v-leave-active{
animation: shake 10s;
transition: color 3s ease-in;
}
.v-leave-from{
color: seagreen;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
show: false
}
},
methods:{
shift(){
this.show = !this.show;
}
},
// type="transition" 表示以过渡效果为准
// type="animation" 表示以动画效果为准
template: `
<div>
<transition type="transition">
<div v-if="show">hello world!</div>
</transition>
<button @click="shift">切换</button>
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
运行结果
image-20210613230514709.png统一设置动画和过渡效果执行时长
执行的节奏还是按钮原本设置的,这里只是设置多长事件结束效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 样式 -->
<style>
@keyframes shake {
0%{
transform: translateX(-100px);
}
50%{
transform: translateX(-50px);
}
100%{
transform: translateX(50px);
}
}
/* 入场动画 */
.v-enter-active {
animation: shake 10s;
transition: color 3s ease-in;
}
.v-enter-from{
color: red
}
/* 出场动画 */
.v-leave-active{
animation: shake 10s;
transition: color 3s ease-in;
}
.v-leave-from{
color: seagreen;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
show: false
}
},
methods:{
shift(){
this.show = !this.show;
}
},
// 1000毫秒后理解结束效果
template: `
<div>
<transition :duration="1000">
<div v-if="show">hello world!</div>
</transition>
<button @click="shift">切换</button>
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
运行结果
image-20210613230923569.png精准设置入场和出场动画时长
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 样式 -->
<style>
@keyframes shake {
0%{
transform: translateX(-100px);
}
50%{
transform: translateX(-50px);
}
100%{
transform: translateX(50px);
}
}
/* 入场动画 */
.v-enter-active {
animation: shake 3s;
transition: color 3s ease-in;
}
.v-enter-from{
color: red
}
/* 出场动画 */
.v-leave-active{
animation: shake 3s;
transition: color 3s ease-in;
}
.v-leave-from{
color: seagreen;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
show: false
}
},
methods:{
shift(){
this.show = !this.show;
}
},
// 1000毫秒后理解结束效果
// 精准控制
template: `
<div>
<transition :duration="{enter: 1000, leave: 3000}">
<div v-if="show">hello world!</div>
</transition>
<button @click="shift">切换</button>
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
运行结果
image-20210613231216779.png使用js做动画
代码演示了入场动画,出场动画也类似
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>hello vue</title>
<!-- 引入Vue库 -->
<script src="https://unpkg.com/vue@next"></script>
<!-- 样式 -->
<style>
@keyframes shake {
0%{
transform: translateX(-100px);
}
50%{
transform: translateX(-50px);
}
100%{
transform: translateX(50px);
}
}
/* 入场动画 */
.v-enter-active {
animation: shake 3s;
transition: color 3s ease-in;
}
.v-enter-from{
color: red
}
/* 出场动画 */
.v-leave-active{
animation: shake 3s;
transition: color 3s ease-in;
}
.v-leave-from{
color: seagreen;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script>
const app = Vue.createApp({
data(){
return{
show: false
}
},
methods:{
shift(){
this.show = !this.show;
},
// 动画执行前
handleBeforeEnter(el){
el.style.color = 'red';
},
// 动画执行中
handleEnterActive(el, done){
// 每隔 1s 执行
const animation = setInterval(() => {
if(el.style.color === 'red'){
el.style.color = 'blue'
}else{
el.style.color = 'red'
}
}, 1000);
// 5s 后执行:清除定时器
setTimeout(() => {
clearInterval(animation);
// 执行 done() 表示动画执行结束了
done();
}, 5000);
},
// 动画执行后
handleAfterEnter(el){
console.log("动画执行结束了!");
}
},
template: `
<div>
<transition
:css="false"
@before-enter="handleBeforeEnter"
@enter="handleEnterActive"
@after-enter="handleAfterEnter"
>
<div v-if="show">hello world!</div>
</transition>
<button @click="shift">切换</button>
</div>
`
});
const vm = app.mount('#root');
</script>
</html>
网友评论