Vue内置组件
内置组件可以直接在模板中使用,而不需注册。
<keep-alive>
、<transition>
、<transition-group>
和<teleport>
组件都可以被打包工具 tree-shake。所以它们只会在被使用的时候被引入。如果你需要直接访问它们,也可以将它们显性导入。
// Vue 的 CDN 构建版本 const { KeepAlive, Teleport, Transition, TransitionGroup } = Vue
// Vue 的 ESM 构建版本 import { KeepAlive, Teleport, Transition, TransitionGroup } from 'vue'
<component>
和<slot>
是模板语法中组件形式的特性。它们不是真正的组件且无法像上述组件那样被导入。
可以使用unplugin-vue-components插件自动导入以及注册组件,省去导入注册的步骤,可直接在模板中直接使用
component
动态组件,这个组件渲染的具体内容由它唯一的props
属性is
决定,is
可以是组件、字符串、vNode
keep-alive
Props:
include
-string | RegExp | Array
。只有名称匹配的组件会被缓存。exclude
-string | RegExp | Array
。任何名称匹配的组件都不会被缓存。max
-number | string
。最多可以缓存多少组件实例。用法:
<keep-alive>
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和<transition>
相似,<keep-alive>
是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。当组件在
<keep-alive>
内被切换时,它的mounted
和unmounted
生命周期钩子不会被调用,取而代之的是activated
和deactivated
。(这会运用在<keep-alive>
的直接子节点及其所有子孙节点。)主要用于保留组件状态或避免重新渲染。 官方文档
上面是官方对这个内置组件的说明,简单来说就是使用keep-alive
组件包裹的组件再被切换的时候组件本身以及其状态会被缓存起来,而不是销毁
一个小demo说明keep-alive的作用
Tab1.vue:
<template>
<div>
tab1
{{count}}
<button @click="add">add</button>
</div>
</template>
<script setup name='tab1'>
const count = $ref(0);
const add = ()=>count++;
</script>
<style scoped>
</style>
Tab2.vue:
<template>
<div>
tab2
{{count}}
<button @click="add">add</button>
</div>
</template>
<script setup name='tab1'>
const count = $ref(0);
const add = ()=>count++;
</script>
<style scoped>
</style>
Tab3.vue:
<template>
<div>
tab3
{{count}}
<button @click="add">add</button>
</div>
</template>
<script setup name='tab1'>
const count = $ref(0);
const add = ()=>count++;
</script>
<style scoped>
</style>
index.vue:
<template>
<div>
<button @click="changeTab('Tab1')">tab1</button>
<button @click="changeTab('Tab2')">tab2</button>
<button @click="changeTab('Tab3')">tab3</button>
<br />
keep-alive:
<keep-alive>
<component :is="activeComponent"></component>
</keep-alive>
common:
<component :is="activeComponent"></component>
</div>
</template>
<script setup name='ComponentExc'>
import Tab1 from './Tab1.vue';
import Tab2 from './Tab2.vue';
import Tab3 from './Tab3.vue';
const tabs = { Tab1, Tab2, Tab3 }
const activeKey = $ref('Tab1');
const activeComponent = computed(() => tabs[activeKey]);
const changeTab = (key) => activeKey = key;
</script>
<style scoped>
</style>
上面这个demo中每个Tab都拥有自己的状态count
,并且拥有一个按钮对count
进行累加操作,在tab1下将有keep-alive
包裹和无keep-alive
包裹的组件中的count
都累加到5
:
然后切到其他tab,之后切回tab1:
这就是keep-alive的作用
transition和transition-group
动画组件详情参考 官方
slot(插槽)
插槽是Vue提供的一个用于分发渲染内容的内置组件,插槽一共分为三种:
- 默认插槽
默认插槽就是不指定插槽的name,直接通过
<slot></slot>
来使用,这样的插槽在每个组件当中只允许有一个,如果出现了多个,会报下这个错误:
父组件中:
<ChildComponent>
<template v-slot>
我是默认插槽
</tepmlate>
</ChildComponent>
或者
<ChildComponent>
我是默认插槽
</ChildComponent>
子组件中:
<template>
<slot />
</template>
- 具名插槽
具名插槽就是指定插槽的name,直接通过<slot name="***"></slot>
来使用,这样的插槽在每个组件当中可以由若干个
父组件中:
<ChildComponent>
<template v-slot:header>
我是header
</tepmlate>
</ChildComponent>
子组件中:
<template>
<slot name="header" />
</template>
- 作用域插槽
在封装组件的过程中,可以为预留的 插槽绑定
props
数据,这种带有props
数据的插槽叫做“作用域插槽”
父组件中:
<ChildComponent>
<template v-slot:scopeSlot="{a,b}">
我是作用域插槽,我的props带的参数a={{a}},b={{b}}
</tepmlate>
</ChildComponent>
子组件中:
<template>
<slot name="scopeSlot" a="1" b="2" />
</template>
跟 v-on
和 v-bind
一样,v-slot
也有缩写,即把参数之前的所有内容 v-slot:
替换为#
,也就是说上面这个例子中的v-slot:scopeSlot="{a,b}"
可以简写为#scopeSlot="{a,b}"