内置组件
内置组件
Transition动画组件
为单个元素或组件提供动画过渡效果
事件
提示
@before-enter
@before-leave @enter
@leave
@appear
@after-enter
@after-leave
@after-appear
@enter-cancelled
@leave-cancelled (v-show only)
@appear-cancelled
示例
简单元素:
<Transition>
<div v-if="ok">toggled content</div>
</Transition>
通过改变 key 属性来强制过度执行:
<Transition>
<div :key="text">{{ text }}</div>
</Transition>
动态组件,初始渲染时带有过渡模式 + 动画出现:
<Transition name="fade" mode="out-in" appear>
<component :is="view"></component>
</Transition>
监听过渡事件:
<Transition @after-enter="onTransitionComplete">
<div v-show="ok">toggled content</div>
</Transition>
基本慨念
1、包裹内容:
<Transition>
组件通常包裹一个或多个元素或组件。当这些被包裹的内容的状态(如 v-if 或 v-show 的值)发生变化时,<Transition>
会自动应用过渡效果。2、CSS 类名:
<Transition>
组件在元素或组件的不同过渡阶段自动添加或移除特定的 CSS 类名。这使得开发者可以通过 CSS 定义过渡效果,如渐变、滑动、淡入淡出等。3、过渡模式:
<Transition>
组件支持多种过渡模式,如 in-out(先进入,后离开)和 out-in(先离开,后进入),通过 mode 属性来设置。4、钩子函数:Vue 提供了 JavaScript 钩子函数,允许开发者在过渡的不同阶段执行自定义逻辑,如手动操作 DOM 或执行动画库的方法。
使用方法
<template>
<button @click="show = !show">Toggle</button>
<Transition name="fade">
<div v-if="show">Hello, Vue 3!</div>
</Transition>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const show = ref(true);
</script>
<style scoped>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
通用过渡类名
从 Vue 3.x 开始,过渡类名的命名规则发生了一些变化,变得更加直观:
v-leave-from: 表示进入过渡的初始状态。
v-enter-active: 同样表示过渡生效时的状态。
v-enter-to: 表示进入过渡结束后的状态。 以及离开过渡的类名:
v-leave-from: 离开过渡的初始状态。
v-leave-active: 离开过渡生效时的状态。
v-leave-to: 离开过渡的最终状态。
提示
.v-leave-from 和 .v-leave-from 存在的时间非常的短暂,是过渡开始瞬间的状态,在下一个帧被移除。
.v-enter-active 和 .v-leave-active 这两个是真正的动画播放时间,覆盖整个过渡过程,可以用来定义持续时间、延迟和动画曲线等。
v-enter-to 和 v-leave-to 分别表示进入过渡结束状态和离开过渡结束状态,在过渡完成时被添加。
<style>
/*通用过渡动画*/
/* 进入时 */
.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>
<transition>
<div v-if="isActive" class="emoji">🌳</div>
</transition>
<transition>
<div v-if="isActive" class="emoji">🥕</div>
</transition>
<button type="button" @click="isActive=!isActive">请按下</button>

特定过渡类名(定制动画)
定制特定动画是使用 name
替换 v-
前缀的部分,如果你在 <transition>
组件上指定了一个 name 属性,那么这个名称将会作为前缀添加到默认的过渡类名上。例如,如果设置了 name="custom"
,那么过渡类名会变为:
- 进入:
.custom-enter-from
,.custom-enter-active
,.custom-enter-to
- 离开:
.custom-leave-from
,.custom-leave-active
,.custom-leave-to
这样可以让你为不同组件或不同类型的过渡设置不同的动画类名,避免样式冲突,并提高代码的可读性。
<style>
/*定制动画*/
.slide-enter-from{
opacity: 0;
transform: translateX(30px);
}
.slide-enter-active{
transform: .3s;
}
.slide-enter-to{
opacity: 1;
}
.slide-leave-from{
opacity: 1;
}
.slide-leave-active{
transform: .3s;
}
.slide-leave-to{
opacity: 0;
transform: translateX(30px);
}
</style>
<transition>
<div v-if="isActive" class="emoji">🌳</div>
</transition>
<transition name="slide">
<div v-if="isActive" class="emoji">🥕</div>
</transition>

动画过渡简写
在CSS中,当你直接在animation
属性中指定动画名称和持续时间,如animation: pulse 1s
;,是一种简化的写法。CSS动画属性可以包含多个子属性值这与普通动画一样,包括:
- animation-name(动画名称)
- animation-duration(动画持续时间)
- animation-timing-function(动画速度曲线)
- animation-delay(动画延迟)
- animation-iteration-count(动画重复次数)
- animation-direction(动画播放方向)
<style>
.pluse{
animation-name:pluse;
animation-duration: 1s;
animation-iteration-count: infinite;
}
/* 使用3D可以css性能优化->渲染交给GPU加速 动画不要影响周围的文档流*/
@keyframes pluse{
from{
transform: scale3d(1,1,1);
}
50%{
transform: scale3d(1.5,1.5,1.5);
}
to{
transform: scale3d(1,1,1);
}
}
.pulse-enter-active{
animation:pluse 1s
}
.pulse-leave-active{
animation:pluse 1s
}
</style>
<transition>
<div v-if="isActive" class="emoji">🌳</div>
</transition>
<transition name="pulse">
<div v-if="isActive" class="emoji">🥕</div>
</transition>
当你只写了animation: pulse 1s
;,这意味着你仅提供了animation-name
(这里是pulse)和animation-duration
(1秒),而其他子属性将使用其默认值。 关于from
和to
当你省略了它们,实际上是在使用了0%(相当于from
)和100%(相当于to
)的隐含关键字。

动画库animate
Animate.css
是一个非常流行的CSS动画库,它提供了很多预设的动画效果,可以很容易地给网页元素添加动态效果,而无需编写复杂的动画代码
1、安装Animate.css库 要使用 Animate.css,首先安装Animate.css库
npm i animate.css
2、应用动画类: 在你想要添加动画效果的HTML元素上,添加对应的Animate.css类。 这里我们使用enter-active动画使用tada类似“摇晃”的动画效果,leave-active动画使用bounce 会让元素执行一种弹跳动画效果。
3、使用
/*在style中导入css文件*/
@import './styles/animation.css';
<transition
enter-active-class="animate__animated animate__tada"
leave-active-class="animate__animated animate__bounce"
>
animate__animated
是一个必需的基础类,表示该元素将执行动画,而animate__tada
和animate__bounce
则是具体的动画效果类名。

Teleport传送组件
Teleport 是一种能够将我们的模板移动到 DOM 中 Vue app 之外的其他位置的技术。
如果我们嵌套在 Vue 的某个组件内部,那么处理嵌套组件的定位、z-index 和样式就会变得很困难。 使用Teleport 就可以方便的解决组件间 css 层级问题
主要解决的问题 因为Teleport节点挂载在其他指定的DOM节点下,完全不受父级style样式影响
Teleport 怎么使用
要使用teleport,首先要在页面上添加一个元素,我们要将模态内容移动到该页面 下面举个例子
// index.html
<body>
...
<div id="app"></div><!--Vue mounting element-->
<div id="modal-wrapper">
<!--modal should get moved here-->
</div>
</body>
我们将模态内容包装在 teleport 组件中,还需要指定一个 to 属性,为该属性分配一个查询选择器,以标识目标元素,在本例中为 #modal-wrapper
// App.vue
<template>
<button @click="toggleModalState">Open modal</button>
<teleport to="#modal-wrapper">
<modal v-if="modalOpen">
<p>Hello, I'm a modal window.</p>
</modal>
</teleport>
</template>
teleport 中的任何内容都将渲染在目标元素中
案例
通过to 属性 插入指定元素位置 to="body" 便可以将Teleport 内容传送到指定位置
<Teleport to="body">
<Loading></Loading>
</Teleport>
也可以自定义传送位置 支持 class id等 选择器
<div id="app"></div>
<div class="modal"></div>
<Teleport to=".modal">
<Loading></Loading>
</Teleport>
也可以使用多个
<Teleport to=".modal1">
<Loading></Loading>
</Teleport>
<Teleport to=".modal2">
<Loading></Loading>
</Teleport>
defer延迟属性 3.5+
Teleport组件的作用是将children中的内容传送到指定的位置去,比如下面的代码:
<div id="target"></div>
<Teleport to="#target">被传送的内容</Teleport>
文案被传送的内容最终会渲染在id="target"
的div元素中。
在之前有个限制,就是不能将<div id="target">
放在Teleport
组件的后面。
这个也很容易理解DOM是从上向下开始渲染的,如果先渲染到Teleport
组件。然后就会去找id的值为target
的元素,如果找不到当然就不能成功的将Teleport
组件的子节点传送到target
的位置。
在3.5中为了解决这个问题,在Teleport
组件上新增了一个defer
延迟属性。
加了defer
延迟属性后就能将target
写在Teleport
组件的后面,代码如下:
<Teleport defer to="#target">被传送的内容</Teleport>
<div id="target"></div>
defer
延迟属性的实现也很简单,就是等这一轮渲染周期结束后再去渲染Teleport
组件。所以就算是target
写在Telepor
t组件的后面,等到渲染Teleport
组件的时候target
也已经渲染到页面上了。
Suspense异步组件
等待异步组件时渲染一些额外内容,让应用有更好的用户体验
使用步骤:
异步引入组件
import {
defineAsyncComponent} from 'vue'
const Child = defineAsyncComponent(()=>import('./components/Child.vue'))
使用Suspense包裹组件,并配置好default与 fallback
<template>
<div class="app">
<h3>我是App组件</h3>
<Suspense>
//default:就是组件要显示的内容
<template v-slot:default>
<Child/>
</template>
//fallback:就是组件没加载完全的“备胎”
<template v-slot:fallback>
<h3>加载中.....</h3>
</template>
</Suspense>
</div>
</template>
keep-alive缓存组件
Vue 的 keep-alive 是一个非常实用的内置组件,主要用于缓存组件。在一些场景下,它能够提升用户体验,减少性能开销
keep-alive是什么
keep-alive 是 Vue 的一个内置抽象组件,通常用于缓存动态组件或路由组件。被 keep-alive 包裹的组件在切换时不会被销毁,而是会被缓存下来,下一次切换回这个组件时,会直接复用之前的实例,保持其状态。
<template>
<keep-alive>
<component :is="view"></component>
</keep-alive>
</template>
<script>
export default {
data() {
return {
view: 'MyComponent'
};
}
};
</script>
MyComponent 在被切换时不会被销毁,而是会被缓存,当再次展示时,状态和数据都保持不变。
keep-alive 配置选项
keep-alive 提供了几个有用的属性和钩子:
1、include 和 exclude: 用于控制哪些组件需要缓存,支持字符串、正则表达式或数组。
<keep-alive include="ComponentA, ComponentB" exclude="ComponentC">
<router-view></router-view>
</keep-alive>
2、max: 用于指定缓存的组件数量,当超出这个数量时,最久未使用的组件实例将被销毁。
<keep-alive :max="10">
<router-view></router-view>
</keep-alive>
生命周期
keep-alive 还引入了两个新的组件生命周期钩子,用于处理缓存组件:
onActivated:当组件被激活时触发(即从缓存中恢复时)。 onDeactivated:当组件被停用时触发(即被缓存时)。
export default {
activated() {
console.log('组件被激活了');
},
deactivated() {
console.log('组件被缓存了');
}
};