In the code example below (referenced in VueJS Official Site) :
<script setup>
import Home from './Home.vue'
import Posts from './Posts.vue'
import Archive from './Archive.vue'
import { ref, watch } from 'vue'
let currentTab = ref('Home')
const tabs = {
Home,
Posts,
Archive
}
watch(currentTab, (currentTab) => console.log(tabs[currentTab], currentTab))
</script>
<template>
<div class="demo">
<button
v-for="(_, tab) in tabs"
:key="tab"
:class="['tab-button', { active: currentTab === tab }]"
@click="currentTab = tab"
>
{{ tab }}
</button>
<component :is="tabs[currentTab]" class="tab"></component>
</div>
</template>
<style>
.demo {
font-family: sans-serif;
border: 1px solid #eee;
border-radius: 2px;
padding: 20px 30px;
margin-top: 1em;
margin-bottom: 40px;
user-select: none;
overflow-x: auto;
}
.tab-button {
padding: 6px 10px;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
border: 1px solid #ccc;
cursor: pointer;
background: #f0f0f0;
margin-bottom: -1px;
margin-right: -1px;
}
.tab-button:hover {
background: #e0e0e0;
}
.tab-button.active {
background: #e0e0e0;
}
.tab {
border: 1px solid #ccc;
padding: 10px;
}
</style>
taken from
Code Example Reference on VueJS Official Page
... when i pass variable 'currentTab' to :is attribute (instead of tabs[currentTab], as below:
<component :is="currentTab" class="tab"></component>
... strangely the component stop showing, despite the fact value of variable 'currentTab' should resolve into the string value of a Component Name on which we click (like, 'Home', or 'Posts', or 'Archive' as you can see the value of variable that i display using console.log through "watch()" ).
So, the code works only when i pass "tabs[currentTab]" to :is attribute or when i pass the string name of the component (Home, or Posts, or Archive) as below:
<component :is="Archive" class="tab"></component>
// shows only Archive
OR
<component :is="tabs[currentTab]" class="tab"></component>
//Shows component w.r.t tab clicked.
If the variable 'currentTab' should resolve into its value to give:
<component :is="Archive" class="tab"></component>
// shows only Archive
... then why there is strange behavior in resulting view ?
In case of :is="Archive"
and :is="tabs[currentTab]"
the value is a component, while in case of :is="currentTab"
it's a string.
It should either be used with a map of components like tabs
, or resolved prior to usage:
let currentTabComp = computed(() => resolveComponent(currentTab.value))
This is not well-supported by script setup
syntax, in order for this to work, the components need to be explicitly registered in component components
option with regular script
.