Vue爬坑记-----(4)Vue 组件相关

87 阅读3分钟

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

1.png

然后切到其他tab,之后切回tab1:

2.png

这就是keep-alive的作用

transition和transition-group

动画组件详情参考 官方

slot(插槽)

插槽是Vue提供的一个用于分发渲染内容的内置组件,插槽一共分为三种:

  1. 默认插槽 默认插槽就是不指定插槽的name,直接通过<slot></slot>来使用,这样的插槽在每个组件当中只允许有一个,如果出现了多个,会报下这个错误:

截屏2022-04-21 下午6.18.25.png

父组件中:

<ChildComponent>
    <template v-slot>
        我是默认插槽
    </tepmlate>
</ChildComponent>

或者

<ChildComponent>
    我是默认插槽
</ChildComponent>

子组件中:

<template>
    <slot />
</template>
  1. 具名插槽
    具名插槽就是指定插槽的name,直接通过<slot name="***"></slot>来使用,这样的插槽在每个组件当中可以由若干个

父组件中:

<ChildComponent>
    <template v-slot:header>
        我是header
    </tepmlate>
</ChildComponent>

子组件中:

<template>
    <slot  name="header" />
</template>
  1. 作用域插槽 在封装组件的过程中,可以为预留的 插槽绑定 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-onv-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 v-slot:替换为#,也就是说上面这个例子中的v-slot:scopeSlot="{a,b}"可以简写为#scopeSlot="{a,b}"