vue2x,3.x之内置组件
1. component
在Vue中,内置组件component是一个动态地渲染不同组件的元素。它可以根据数据动态地选择要渲染的组件,并在渲染过程中动态地创建和销毁这些组件。
⏰ 父组件
<template> <h1>我是 APP 组件</h1> <button @click="myId = 'my_com'">首页</button> <button @click="myId = 'my_com2'">分类</button> <button @click="myId = 'my_com3'">购物车</button> <button @click="myId = 'my_com4'">个人页</button> <component :is="myId"></component> </template> <script> import my_com from './components/my_com.vue' import my_com2 from './components/my_com2.vue' import my_com3 from './components/my_com3.vue' import my_com4 from './components/my_com4.vue' export default { data() { return { myId: 'my_com' } }, components: { my_com, my_com2, my_com3, my_com4, } } </script>
⏰ my_com 子组件
<template> <h4 style="color: red;">我是首页部分</h4> <input type="text"> </template>
⏰ my_com2 子组件
<template> <h4 style="color: green">我是分类部分</h4> <input type="text" /> </template>
⏰ my_com3 子组件
<template> <h4 style="color: blue;">我是购物车部分</h4> <input type="text"> </template>
⏰ my_com4 子组件
<template> <h4 style="color: purple;">我是个人页部分</h4> <input type="text" /> </template>
2.keep-alive
⏰ 父组件
<template> <h1>我是 APP 组件</h1> <button @click="myId = 'my_com'">首页</button> <button @click="myId = 'my_com2'">分类</button> <button @click="myId = 'my_com3'">购物车</button> <button @click="myId = 'my_com4'">个人页</button> <!-- keep-alive 内置组件 内部可以书写多个组件,可以让内部书写的所有组件,全部具有缓存性 也就组件切换后,对组件内部的一些操作,会被保留下来 当前组件 还有两个属性,两个属性值是一个数组 inclode, 内部包含具备缓存性的组件名 exclode, 内部不包含具有缓存性的组件名 组件名需要是 组件内部书写 name 属性 --> <keep-alive :include="['my_com', 'my_com4']"> <component :is="myId"></component> </keep-alive> </template> <script> import my_com from "./components/my_com.vue"; import my_com2 from "./components/my_com2.vue"; import my_com3 from "./components/my_com3.vue"; import my_com4 from "./components/my_com4.vue"; export default { data() { return { myId: "my_com", }; }, components: { my_com, my_com2, my_com3, my_com4, }, }; </script>
⏰ my_com 子组件
<template> <h4 style="color: red">我是首页部分</h4> <input type="text" /> </template> <script> export default { name: "my_com", }; </script>
⏰ my_com2 子组件
<template> <h4 style="color: green">我是分类部分</h4> <input type="text" /> </template>
<script> export default{ name: 'my_com2' } </script>
⏰ my_com3 子组件
<template> <h4 style="color: blue;">我是购物车部分</h4> <input type="text"> </template>
<script> export default{ name: 'my_com3' } </script>
⏰ my_com4 子组件
<template> <h4 style="color: purple;">我是个人页部分</h4> <input type="text" /> </template>
<script> export default{ name: 'my_com4' } </script>
3.Transition
Vue的Transition是Vue.js提供的一种动画效果管理工具,用于在元素进入或离开DOM时添加动画效果。通过Transition组件,你可以为元素的进入和离开过程分别定义动画效果,比如淡入淡出、滑动等。Transition组件可以包裹任意元素或组件,并通过设置不同的属性来控制动画的行为。
Transition组件的主要属性包括:
- name:指定动画效果的名称,用于在CSS中定义对应的动画样式。
- appear:指定是否在初始渲染时触发动画效果。
- duration:指定动画的持续时间。
- mode:指定动画模式,可以是"in-out"、"out-in"或默认的"out-in"。
通过使用Transition组件,你可以轻松地为Vue应用中的元素添加动画效果,使用户体验更加丰富和生动。
🌰 代码演示
<template> <button @click="flag = !flag">隐藏/展示 p 标签</button> <Transition> <p v-if="flag">飞流直下三千尺,疑是银河落九天</p> </Transition> </template> <script> export default { data() { return { flag: false, }; }, }; </script> <style scoped> .v-enter-active, .v-leave-active { transition: opacity 0.5s ease; } .v-enter-from, .v-leave-to { opacity: 0; } </style>
4.Teleport
Vue的Teleport是Vue.js 3.x版本新增的特性,它允许你将组件的内容渲染到DOM中的任何位置,而不受组件层次结构的限制。通过Teleport,你可以将组件的内容渲染到DOM中的任意位置,比如body元素下面,这样可以在组件内部实现全局级别的渲染,而不需要改变组件的层次结构。
Teleport使用一个特殊的<teleport>标签来包裹要渲染的内容,然后通过to属性指定要渲染到的目标位置,可以是CSS选择器、DOM元素或Vue组件的引用。这样,无论组件在DOM中的位置如何变化,渲染的内容都会被移动到指定的目标位置。
🌰下面是一个使用Teleport的示例:
<template> <teleport to="body"> <div v-show="showModal" class="modal"> <!-- modal content --> </div> </teleport> <button @click="showModal = !showModal">Toggle Modal</button> </template> <script> export default { data() { return { showModal: false, }; }, }; </script>
在这个示例中,<div class="modal">的内容会被渲染到body元素下面,而不是组件自身的位置。这样可以实现全局级别的渲染,而不需要改变组件的层次结构。
总之,Teleport是Vue.js 3.x中非常有用的特性,它可以帮助你更灵活地控制组件的渲染位置,提高了组件的复用性和灵活性。
5.Suspense
Suspense 组件是 Vue3 新增的内置组件之一。它允许我们的应用程序在等待异步组件的同时渲染一些备用内容,让我们创造一个流畅的用户体验。
⏰ 什么是
Suspense组件?
Suspense 组件用于在等待某种异步组件解析时显示回退内容。
❓ 您可能会想,我们什么时候会使用异步组件?
老实说,比你想象的要多。每当我们希望我们的组件等待它获取数据(通常是在异步 API 调用中)时,我们可以使用 Vue3 Composition API 创建一个异步组件。
以下是一些异步组件有用的实例:
- 在加载页面之前显示加载动画
- 显示占位符内容
- 处理延迟加载的图像
- etc
以前,在 Vue2 中,我们必须使用条件(例如 v-if 或 v-else)来检查数据是否已加载并显示回退内容。但是现在,Vue3 内置了 Suspense,所以我们不必担心数据加载时的跟踪和相应内容的渲染。
⏰ 如何使用 Suspense 组件?
有两种类型的异步依赖可以等待
<Suspense>:
- 带有
async setup()钩子的组件。这包括使用<script setup>顶级await表达式的组件。- 异步组件。
🌰 例如,我们有一个 TodoInfo 组件,其中使用了 <script setup>,该组件在完全渲染前异步加载一些数据。
<template> <h1>{{ title }}</h1> </template> <script setup> const getTodoInfo = async () => { return await fetch('https://jsonplaceholder.typicode.com/todos/1') .then(response => response.json()) .then(json => json) } var { title } = await getTodoInfo() </script>
然后,我们有一个 TodoList.vue 组件,其中包含 TodoInfo 组件。
如果我们要在等待组件获取数据并解析时显示 Loading... 之类的内容,只需要三步:
- 将异步组件包装在
<template #default>标签中 - 在异步组件旁边添加一个同级的
<template #fallback>标签 - 将两个组件包装在
<Suspence>组件中
使用插槽,Suspense 将渲染备用内容,直到默认内容准备就绪为止。然后,它会自动切换到显示我们的异步组件。
它看起来有点像这样。
<Suspense> <template #default> <todo-info/> </template> <template #fallback> <div>Loading...</div> </template> </Suspense>
⏰ 捕获组件错误
当我们使用异步组件时,我们还可以捕获错误并向用户显示一些错误消息。
在 Vue2 中,我们可以使用 errorCaptured 钩子,但是在 Vue3 中,它已重命名为 onErrorCaptured。
不管它被命名为什么,当任何子代组件的错误被捕获时,这个钩子就会运行。我们可以在 Suspense 中使用这个来渲染出错时的错误。
如果我们处理错误以显示错误消息,那么上面的组件就是这样的。
<template> <div v-if="errMsg"> {{ errMsg }} </div> <Suspense v-else> <template #default> <todo-info/> </template> <template #fallback> <div>Loading...</div> </template> </Suspense> </template> <script setup> import { onErrorCaptured } from 'vue' const errMsg = ref(null) onErrorCaptured(e => { errMsg.value = '出错了!' return true }) </script>
6.slot
⏰ slot是什么 ?
slot,也称插槽,可以类比为插卡式的FC游戏机,游戏机(子组件)暴露卡槽(插槽)让用户插入不同的游戏磁条(自定义内容),游戏机会读取并加载磁条里的游戏。 Vue的slot,是组件的一块HTML模版,这块模版由使用组件者即父组件提供。可以说是子组件暴露的一个让父组件传入自定义内容的接口。
⏰ slot的作用
slot的用法可以分为三类,分别是默认插槽、具名插槽和作用域插槽 子组件中:
- 插槽用标签来确定渲染的位置,里面放如果父组件没传内容时的后备内容
- 具名插槽用name属性来表示插槽的名字,不传为默认插槽
- 作用域插槽在作用域上绑定属性来将子组件的信息传给父组件使用,这些属性会被挂在父组件slot-scope接受的对象上。
Child.vue
<template> <div> <main> <!-- 默认插槽 --> <slot> <!-- slot内为后备内容 --> <h3>没传内容</h3> </slot> </main> <!-- 具名插槽 --> <header> <slot name="header"> <h3>没传header插槽</h3> </slot> </header> <!-- 作用域插槽 --> <footer> <slot name="footer" testProps="子组件的值"> <h3>没传footer插槽</h3> </slot> <footer> </div> </template>
父组件中在使用时:
- 默认插槽的话直接在子组件的标签内写入内容即可
- 具名插槽是在默认插槽的基础上加上slot属性,值为子组件插槽name属性值
- 作用域插槽则是通过slot-scope获取子组件的信息,在内容中使用。这里可以用解构语法去直接获取想要的属性
Parent.vue
<child> <!-- 默认插槽 --> <div>默认插槽</div> <!-- 具名插槽 --> <div slot="header">具名插槽header</div> <!-- 作用域插槽 --> <div slot="footer" slot-scope="slotProps"> {{slotProps.testProps}} </div> </child>
渲染结果为

⏰ v-slot
⚠️ 在vue2.6中,上述的API被软废弃(3.0正式废弃),取而代之的是内置指令v-slot,可以缩写为【#】
子组件用法保持不变,父组件中
- slot属性弃用,具名插槽通过指令参数v-slot:插槽名 的形式传入,可以简化为 #插槽名。
- slot-scope属性弃用,作用域插槽通过v-slot:xxx="slotProps"的slotProps来获取子组件传出的属性
- v-slot属性只能在
<template>上使用,但在【只有默认插槽时】可以在组件标签上使用
Parent
<template> <child> <!--默认插槽--> <template v-slot> <div>默认插槽</div> </template>
<!--具名插槽--> <template #header> <div>具名插槽</div> </template>
<!--作用域插槽--> <template #footer="slotProps"> <div> {{slotProps.testProps}} </div> </template> <child> </template>
🍀 拓展用法:
同样可以通过解构获取v-slot={user}, 还可以重命名v-slot="{user: newName}"和定义默认值v-slot="{user = '默认值'}" 插槽名可以是动态变化的 v-slot:[slotName]
⚠️ 注意:
默认插槽名为default,可以省略default直接写v-slot, 缩写为#时不能不写参数,写成#default(这点所有指令都一样,v-bind、v-on) 多个插槽混用时,v-slot不能省略default
浙公网安备 33010602011771号