在 Vue.js 中,动态效果和动画是提升用户体验的重要组成部分。Vue 提供了内置的 <transition>
组件来方便地添加过渡效果,并且可以使用 CSS transitions 或 animations 来定义这些效果。本文将探讨如何使用 Vue 的 <transition>
组件结合 CSS 和 JavaScript 实现平滑的动画效果。
第一种方式
<script setup>
import { ref } from 'vue';
const name = '大佬开发团';
const isActive = ref(true);
</script>
<template>
<div class="page">
<div class="card">
<div class="card__header">
<h3 class="card-title">{{ name }}</h3>
<div class="card-subtitle">Transition & Animation</div>
</div>
<div class="card__content">
<div :class="['emoji', {hidden: !isActive}]">🌳</div>
</div>
<div class="card__action">
<button type="button" @click="isActive = !isActive;">请按这里</button>
</div>
</div>
</div>
</template>
<style scoped>
@import './styles/app.css';
@import './styles/card.css';
</style>
input[type='text'],
textarea,
select {
padding: 4px 8px;
margin: 8px 0;
margin-right: 8px;
font-size: 16px;
}
label {
margin-left: 4px;
}
.page {
padding: 32px;
margin: 32px;
}
.emoji {
font-size: 80px;
transition: 0.5s;
}
.hidden {
opacity: 0;
transform: translateX(30px);
}
.card {
display: flex;
flex-direction: column;
align-items: center;
max-width: 300px;
box-sizing: border-box;
padding: 32px;
margin: 0 auto;
background: #f8f8f8;
border-radius: 10px;
}
.card__header {
text-align: center;
margin-bottom: 32px;
}
.card-title {
margin-bottom: 8px;
}
.card-subtitle {
font-size: 12px;
color: #989898;
}
.card__content {
min-height: 250px;
}
.card__action > button {
outline: none;
border: none;
background: none;
border: 2px solid #000;
padding: 10px 24px;
cursor: pointer;
margin: 4px;
}
.card__action > button:active {
opacity: 0.8;
}
第二种方式
...
<div class="card__content">
<div :class="['emoji', {pulse: !isActive}]">🌳</div>
</div>
.pulse {
animation-name: pulse;
animation-duration: 1s;
animation-iteration-count: infinite;
}
/* css 性能优化 GPU加速 动画不要影响周围的文档流*/
@keyframes pulse {
from {
transform: scale3d(1, 1, 1);
}
50% {
transform: scale3d(1.5, 1.5, 1.5);
}
to {
transform: scale3d(1, 1, 1);
}
}
第三种方式
...
<div class="card__content">
<!-- <div :class="['emoji', {pulse: !isActive}]">🌳</div> -->
<transition>
<div v-if="isActive" class="emoji">🌳</div>
</transition>
</div>
...
...
/* 进入时 */
.v-enter-from {
opacity: 0;
}
.v-enter-active {
transition: .3s;
}
.v-enter-to {
opacity: 1;
}
/* 离开时 */
.v-leave-from {
opacity: 1;
}
.v-leave-active {
transition: 1s;
}
.v-leave-to {
opacity: 0;
}