1. vue的内置组件的定义

component是vue的内置组件,不需要注册可以直接使用。
通过is去选择要渲染的组件,可以是一个组件名称字符串(使用在选项式API中),也可以是组件的定义(使用在<script setup>组合式 API中)。

interface DynamicComponentProps {
  is: string | Component
}

2. 使用方法

2-1 基本使用

<template>
  <component :is="number > 0.5 ? Child1 : Child2"></component>
</template>
<script setup lang="ts">
import Child1 from './Child1.vue';
import Child2 from './Child2.vue';
const number = ref(0);
onMounted(() => {
  number.value = Math.random();
});
</script>

2-2 动态组件的传值

在这里插入图片描述

在这里插入图片描述

<template>
  <div class="auto-wrap">
    <div class="tabs-wrap">
      <div
        v-for="item in state.tabs"
        :key="item"
        :class="{ 'active-tabs': state.currentTab == item }"
        class="tabs"
        @click="tabsClick(item)">
        {{ item }}
      </div>
    </div>
    <component :is="showTab" :msg="showMsg" class="content"></component>
  </div>
</template>
<script setup lang="ts">
import Child1 from './Child1.vue';
import Child2 from './Child2.vue';
const state = reactive({
  tabs: ['tab1', 'tab2'],
  currentTab: 'tab1',
});
const tabsClick = (tab: string) => {
  state.currentTab = tab;
};
const showTab = computed(() => {
  return state.currentTab == 'tab1' ? Child1 : Child2; //按定义渲染组件
});
const showMsg = computed(() => {
  return state.currentTab == 'tab1' ? 'tab1' : 'tab2';
});
</script>
<style lang="scss" scoped>
.auto-wrap {
  background: #fff;
  display: flex;
  .tabs-wrap {
    width: 100px;
    height: 50px;
    line-height: 50px;
    .tabs {
      border: 1px solid #eee;
      padding: 3px;
      text-align: center;
    }
    .active-tabs {
      color: red;
    }
  }
  .content {
    padding: 12px;
  }
}
</style>

<!-- Child1.vue -->
<template>
  <div>{{props.msg}}</div>
</template>
<script setup lang="ts">
const props = defineProps<{
  msg?: string;
}>();
</script>
<style scoped></style>

<!-- Child2.vue -->
<template>
  <div>{{ props.msg }}</div>
</template>
<script setup lang="ts">
const props = defineProps<{
  msg?: string;
}>();
</script>
<style scoped></style>

2-3 动态组件的缓存

在组件内添加两个生命周期函数:
在这里插入图片描述

当动态组件的切换过程中,原先保存的状态也会丢失。如果想在组件切换时,保留状态,可以用到<KeepAlive> 内置组件。
作用:防止重复渲染DOM,减少加载时的时间及性能消耗。

使用
    <keep-alive>
      <component :is="showTab" :msg="showMsg" class="content"></component>
    </keep-alive>

<KeepAlive>中可以传入三个参数:
include: 匹配的组件才会被缓存,匹配的模式可以是字符串或者正则表达式
exclude: 匹配的组件都不会被缓存
max:最多可以缓存多少组件实例

interface KeepAliveProps {
  /**
   * 如果指定,则只有与 `include` 名称
   * 匹配的组件才会被缓存。
   */
  include?: MatchPattern
  /**
   * 任何名称与 `exclude`
   * 匹配的组件都不会被缓存。
   */
  exclude?: MatchPattern
  /**
   * 最多可以缓存多少组件实例。
   */
  max?: number | string
}

type MatchPattern = string | RegExp | (string | RegExp)[]

<KeepAlive> 是一个抽象组件,不会被实际渲染成DOM,类似的有<Transition><Teleport>等。

生命周期函数

<KeepAlive> 包裹的组件会多出两个生命周期函数:
onActivated: 组件被激活时调用
onDeactivated: 组件离开时调用
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

activated 在组件挂载时也会调用,并且 deactivated 在组件卸载时也会调用。
这两个钩子不仅适用于 缓存的根组件,也适用于缓存树中的后代组件。

也可以与 <Transition> 一起使用

    <KeepAlive>
      <Transition>
        <component :is="showTab" :msg="showMsg" class="content"></component>
      </Transition>
    </KeepAlive>
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐