点击上方 程序员成长指北,关注公众号
回复1,加入高级Node交流群
在现代的网页开发中,动画效果不仅能够增强用户体验,让网页变得更加生动和有趣,而且丰富的动画效果也是面试大厂的加分项。Vue.js 提供了强大的工具和内置组件,使得创建和管理动画效果变得更加简单和高效。在本文中,我们将详细介绍如何在 Vue 中使用动画,并提供一些最佳实践来帮助你编写高质量的动画代码。
页面动态效果
在 Vue 中实现动态效果有多种方法,包括 CSS 属性切换、animation 复杂的动画、JavaScript 样式操作以及 v-if/v-show 切换组件带来动画。下面我们将详细介绍这些方法。
CSS Transition 属性切换
CSS 的 transition
属性可以实现元素在不同状态之间平滑过渡。它是实现简单动画效果的理想选择。
<script setup>
import { ref } from 'vue';
const name = 'VUE动画';
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/animation.css';
@import './styles/card.css';
.emoji {
font-size: 80px;
transition: 0.5s;
}
.hidden {
opacity: 0;
transform: translateX(30px);
}
</style>
在这个示例中,我们使用 transition
属性来实现动画效果。当点击按钮时,isActive
的值会切换,emoji
元素的类名也会随之改变,从而触发 CSS transition 动画。
CSS Animation 属性
对于更复杂的动画效果,可以使用 CSS 的 animation
属性。通过定义关键帧,你可以实现复杂的动画序列。
<script setup>
import { ref } from 'vue';
const name = 'VUE动画';
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', { pulse: 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/animation.css';
@import './styles/card.css';
.emoji {
font-size: 80px;
}
.pulse {
animation: pulse 1s infinite;
}
@keyframes pulse {
from {
transform: scale3d(1, 1, 1);
}
50% {
transform: scale3d(1.5, 1.5, 1.5);
}
to {
transform: scale3d(1, 1, 1);
}
}
</style>
在这个示例中,我们使用 CSS animation
属性实现了一个持续跳动的动画效果。pulse
类通过关键帧定义了动画序列,当 isActive
值改变时,emoji
元素的动画效果会被触发,实现scale 放大到1.5倍再复原的效果。
需注意这里的 scale3d
中的3d 它用于在三维空间中缩放元素。尽管在许多情况下可能只需要在二维空间中进行缩放,但使用 scale3d
具有一些性能优势,尤其是在利用 GPU 加速动画方面,使得动画不要影响周围的文档流。
Vue 提供的内置组件
Vue 提供了一些内置组件来帮助实现动画效果,其中最常用的是 transition
和 animation
。
transition
<transition>
组件可以为单个元素/组件的进入和离开过程添加动画效果。
<script setup>
import { ref } from 'vue';
const name = 'VUE动画';
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">
<transition >
<div v-if="isActive" class="emoji">🥹</div>
</transition>
</div>
<div class="card__action">
<button type="button" @click="isActive = !isActive;">请按这里</button>
</div>
</div>
</div>
</template>
<style scoped>
/* 全局样式 */
@import './styles/app.css';
@import './styles/animation.css';
@import './styles/card.css';
.emoji {
font-size: 80px;
}
./* 进入时 */
.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;
}
</style>
在这个示例中,我们使用了 Vue 的 <transition>
组件且用上了v-if,Vue 的 <transition>
组件通过一系列内置的生命周期钩子类名,使得动画的定制更加灵活和精细。这些钩子类名在元素进入和离开 DOM 时添加和移除,从而实现动画效果。
进入阶段:
.v-enter-from
:在元素被插入之前被添加。代表进入动画的初始状态。.v-enter-active
:在元素被插入时立即被添加。定义进入动画的过渡属性,如transition
或animation
。.v-enter-to
:在进入动画完成时被添加,移除.v-enter-from
。表示进入动画的最终状态。离开阶段:
.v-leave-from
:在元素被移除之前被添加。代表离开动画的初始状态。.v-leave-active
:在元素被移除时立即被添加。定义离开动画的过渡属性,如transition
或animation
。.v-leave-to
:在离开动画完成时被添加,移除.v-leave-from
。表示离开动画的最终状态。
除此之外我们还可以定制transition
,直接给 transition
取一个name
<template>
<transition name="pulse" >
<div v-if="isActive" class="emoji">🥹</div>
</transition>
</template>
<style scoped>
.pulse-enter-active{
animation: pulse 1s;
}
.pulse-leave-active{
animation: pulse 1s ;
}
</style>
且css定义 .name-enter-active
和 .name-leave-active
这样也是可以达到效果的。
animation
我们也可以用上更为丰富的animate
库,里面封装了很多常见且更高级的动画效果,且使用起来非常方便。在这篇文章将以一个动画效果为例,讲述一下animate.css的简单使用。详细可以参考官方文档。Animate.css | A cross-browser library of CSS animations.
首先安装这个库的依赖
npm i animation.css
然后在main.js导入
import 'animate.css'
然后直接在 <transition>
组件中直接使用要添加效果的属性就行了。
<transition class="animate__tada"
enter-active-class="animate__animated animate__tada"
leave-active-class="animate__animated animate__bounce"
>
<div v-if="isActive" class="emoji">🥹</div>
</transition>
其中 animate__tada
和 animate__bounce
是两种效果。
良好的编程风格
最后还是要强调一下要培养一种良好的编程风格,这是进大厂的一个重要的加分项。
下面为完整的代码
<script setup>
import {ref} from 'vue';
// import {} from '';
const name = 'VUE动画';
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',{pulse: !isActive}]">🌲</div> -->
<!-- <transition name="pulse" >
<div v-if="isActive" class="emoji">🥹</div>
</transition> -->
<transition class="animate__tada"
enter-active-class="animate__animated animate__tada"
leave-active-class="animate__animated animate__bounce"
>
<div v-if="isActive" class="emoji">🥹</div>
</transition>
</div>
<div class="card__action">
<button type="button" @click="isActive =!isActive;">请按这里</button>
</div>
</div>
</div>
</template>
<style scoped>
/* 全局样式 */
@import './styles/app.css';
@import './styles/animation.css';
@import './styles/card.css';
</style>
app.css
全局样式
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);
}
/* 进入时 */
.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;
}
.slide-enter-from{
opacity: 0;
transform: translateX(30px);
}
.slide-enter-active{
transition: .3s;
}
.slide-enter-to{
opacity: 1;
/* 默认会返回0 */
}
.slide-leave-from{
opacity: 1;
}
.slide-leave-active{
transition: .3s;
}
.slide-leave-to{
opacity: 0;
transform: translateX(30px);
}
.pulse-enter-active{
animation: pulse 1s;
}
.pulse-leave-active{
animation: pulse 1s ;
}
card.css
.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;
}
animation.css
.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__header">
<h3 class="card__title">{{ name }}</h3>
<div class="card__subtitle">Transition & Animation</div>
</div>
使用了 BEM(Block Element Modifier)命名规范,使 CSS 类名更加语义化和层次分明。且将代码拆分成小的、可复用的组件有助于提高代码的可维护性和复用性。
编写清晰、简洁、语义化的 HTML 和 CSS 代码,可以提高网页的可读性和可维护性。
@import './styles/app.css';
@import './styles/animation.css';
@import './styles/card.css';
使用 @import
将 CSS 模块化,可以更好地组织和管理样式代码。
结语
通过这篇文章,我们学习了如何去使用CSS的动画属性和Vue的内置去实现动画的效果。熟悉掌握这些,我们可以创建出丰富多彩的动态效果,提升用户体验。在实际开发中,选择合适的动画实现方式,并遵循良好的编程规范,可以使我们的代码更加高效和易于维护!如果这篇文章对你有帮助,可以点个赞哦
我组建了一个氛围特别好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你对Node.js学习感兴趣的话(后续有计划也可以),我们可以一起进行Node.js相关的交流、学习、共建。下方加 考拉 好友回复「Node」即可。
“分享、点赞、在看” 支持一波👍