[Vuejs]-Vue3 pass component as prop

4👍

When using <script setup>, the <component>.is prop needs to be set to the component definition itself (not the component’s name).

One solution is to track the active index (instead of active tab component):

  1. Change activeTab to be a computed prop that returns the current tab from tabs[] based on the active index.

  2. Create an activeIndex ref, initialized to 0.

  3. In the v-for, include the index iterator

  4. In the button‘s click handler, set the activeIndex to the current index.

  5. In the class binding, compare the current index to activeIndex.

<script setup>
import { onMounted, ref, computed } from 'vue'

const props = defineProps({
  titles: {},
  tabs: {},
})
         1️⃣
const activeTab = computed(() => props.tabs[activeIndex.value])
         2️⃣
const activeIndex = ref(0)
</script>
<template>
  <div class="bg-white flex items-center rounded-tr rounded-tl shadow border-b border-grey overflow-hidden">
    <button
                       3️⃣
      v-for="(title, index) in titles"
                  4️⃣
      @click="activeIndex = index"
      v-text="title"
      class="font-medium px-4 py-3 hover:bg-grey hover:bg-opacity-70 border-b-2 border-transparent hover:border-primary"
                 5️⃣
      :class="index === activeIndex && 'text-red border-primary bg-grey bg-opacity-70 '"
    />
  </div>
  <div class="bg-white p-4 min-h-[calc(100vh-10rem)]">
    <component :is="activeTab"></component>
  </div>
</template>

Also, make sure to call markRaw() on the component definitions in the binding to avoid the unnecessary overhead of reactivity. This also resolves a Vue warning about this in the browser console.

<template>                                              👇         👇
  <Tab :titles="['Languages', 'Countries']" :tabs="[languages, countries]"> </Tab>
</template>
<script setup>
import { markRaw } from 'vue'
import Tab from '@/components/Tab.vue'
import Countries from '@/components/Countries.vue'
import Languages from '@/components/Languages.vue'
                     👇
const countries = markRaw(Countries)
const languages = markRaw(Languages)
</script>

demo

👤tony19

Leave a comment