和vue3和解的Day26--组合式动态组件

77 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 26 天,点击查看活动详情

说点题外话

说正文

image.png

在模板中,我们使用<component>元素来渲染动态组件,并使用v-bind指令的":is"参数来指定要渲染的子组件。

1. 基本使用

  • App.vue
<template>
  <div>
   <component :is="tabs[currentTab.type]" ></component>
  </div>
</template>

<script setup>
import { reactive } from 'vue';
import Home from './Home.vue';
import HomeContent from './HomeContent.vue';

const currentTab = reactive({
  type: 1
})

/** 这里注意写的是变量Home和HomeContent,不是字符串 */
const tabs = {
  1: Home,
  2: HomeContent
}

</script>

很明显,上面这个案例只能算是基础版本,只能正常的展示数据,不能达到我们日常开发需求。

假如我们需要点击一个按钮对组件进行切换,我们该怎么实现这个代码呢?

2. 点击切换组件

<template>
  <div>
    <button v-for="(item, index) in data.tabs" :key="index" @click="changeTab(item)">{{ item }}</button>
    <component :is="tabParams[data.currentTab]"></component>
  </div>
</template>

<script setup>

import { reactive, shallowReactive } from 'vue';
import Home from './Home.vue';
import HomeContent from './HomeContent.vue';

const data = reactive({
  tabs: ['Home', "HomeContent"],
  currentTab: 'Home'
})

const tabParams = shallowReactive({
  Home, HomeContent
})

const changeTab = item => {
 data.currentTab = item
}
</script>

这里我们会定义一个reactive类型的对象用来存储我们所有需要切换的组件(Home、HomeContent)和当前展示的组件(这里默认是Home组件)。

通过shallowReactive方式注册我们需要切换的组件,这里是Home组件和HomeContent组件。

当我们在<component>标签中切换组件:is属性绑定的时候需要注意要从注册组件的tabParams中去去data中的当前组件信息。

3. 传递参数

如果我们想要给组件传递父组件的参数呢,并且要保证每个组件都能获取到我们传递的参数,我们需要早<component>标签中绑定我们需要传递的参数

  • App.vue
<component :is="tabParams[data.currentTab]" :name="name"></component>

// 操作的数据
const name = ref("传递的参数")

-- Home.vue

<template>
  <div>
    <h2>Home组件-{{ name }}</h2>
  </div>
</template>

<script setup>

const props = defineProps({
  name: String
})

</script>

image.png

此时的界面展示如上图

4. shallowReactive

其实vue3组合式动态组件对于vue2选项式动态组件改动的地方并没有很多,只用在:is属性判断展示哪个组件的时候写法有点区别。需要使用shallowReactive方式注册组件,通过这个变量对查找对应的组件。

那么会有人问,我们注册组件的方法换成reactive不可以吗?

当我们将shallowReactive换成reactive之后,虽然代码和界面展示没有变化,但是会出现如下警告,

image.png

结束