I am trying to develop tabs using Dynamic component in Vue 3.2, but components are not showing up. If I change <component :is=currentTab ></component>
to <A/>
, it shows up, so I think <component></component>
is not working properly, but I don't know why. If you could give me some advice I would appreciate it. Thank you.
<template>
<div >
<div >
<div id="dynamic-component-demo" >
<button
v-for="tab in tabs"
v-bind:key="tab"
v-bind:
v-on:click="currentTab = tab"
>
{{ tab }}
</button>
<component :is=currentTab ></component>
</div>
</div>
</div>
<template>
<script setup lang="ts">
import Shop from './A/A.vue';
import Knowledge from './B/B.vue';
import Community from './C/C.vue';
import router from '../../router';
const currentTab= ref('A');
const tabs = ['A', 'B', 'C']
</script>
CodePudding user response:
Of course it does not work. Your components are not registered by name. How could Vue know that "A"
should be Shop
component?
You have 2 options:
register components globally (app.component()) or locally (not possible with
script setup
- normalscript
must be used alongside thescript setup
). Now you can pass their name asString
intois
and Vue will know what to doOr pass a component object into
:is
instead of string
<template>
<div id="dynamic-component-demo" >
<button
v-for="(tab, i) in tabs"
v-bind:key="tab.name"
v-bind:
v-on:click="currentTab = tabs[i]"
>
{{ tab.name }}
</button>
<component :is="currentTab.comp"></component>
</div>
</template>
<script setup lang="ts">
import { shallowRef } from 'vue'
import Shop from './A.vue';
import Knowledge from './B.vue';
const tabs = [
{ name: 'A', comp: Shop },
{ name: 'B', comp: Knowledge }
]
// using shallowRef to stop Vue from turning component definitions to reactive objects
// use normal ref to see a warning
const currentTab = shallowRef(tabs[0]);
</script>
If I change <component :is=currentTab ></component>
to <A/>
, it shows up
Well I really doubt it - unless, of course, you have your components registered globally somewhere else (in code not shown in the question). If you try to add <A/>
into a <template>
in the linked demo, it does not work...