Home > database >  Dynamic components doesn't work in script setup
Dynamic components doesn't work in script setup

Time:03-29

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:

  1. register components globally (app.component()) or locally (not possible with script setup - normal script must be used alongside the script setup). Now you can pass their name as String into is and Vue will know what to do

  2. Or 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>

Demo

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...

  • Related