skip to Main Content

I have made a tab overview and in order to not overload the api with calls, I put them in a loop like described in the documentation: link

It all works but my tabs have icons and translations and I am unsure how to implement them.

I tried changing the tabs object to an array with the icon and translation inside them, which works but then the < component :is = "tabs[currentTab]" doesnt work anymore, no errors, no console errors, just blank tab.

My question is, how can I use this Vue 3 functionality in script setup with icons and translations?

Here is component:

<ul class="nav nav-tabs nav-fill nav-icons" id="tabsWithIcons" role="tablist">
                <li class="nav-item" role="presentation"
                    v-for="(_, tab) in tabs"
                    :key="tab"
                    :class="['tab-button', { active: currentTab === tab }]"
                    @click="currentTab = tab">
                    <button class="nav-link justify-content-center" :class="[{ active: currentTab === tab }]" id="home-tab" data-bs-toggle="tab" data-bs-target="#home-tab-pane" type="button" role="tab" aria-controls="home-tab-pane" aria-selected="true">
                        <BootstrapIcon icon="share-fill" />
                       <span>{{ tab }}</span>
                    </button>
                </li>
            </ul>
            <div class="tab-content my-4" id="myTabContent">
                <div class="tab-pane fade show active" id="home-tab-pane" role="tabpanel" aria-labelledby="home-tab" tabindex="0">
                  <component :is="tabs[currentTab]"></component>
                </div>
            </div>

And here is the code in my script:

import Home from '@/views/Home.vue'
import Contact from '@/views/Contact.vue'
import AboutMe from '@/views/AboutMe.vue'


import { ref } from 'vue'

const currentTab = ref('Home')

const tabs = {
  Home,
  Contact,
  AboutMe
}

I have tried

Changing the tabs = { } to:

const tabs = [
  { name: 'Home', icon: 'house-fill', translation: i18n('message')} ,
  { name: 'Contact', icon: 'telephone-fill', translation: i18n('message')} ,
  { name: 'AboutMe', icon: 'person-fill', translation: i18n('message')} ,
]

And then the icons and tab labels work (when I change tab to tab.name in the template etc), but the tab content stays empty due to < component :is="tab[currentTab]" not getting it… Also the translations are not working..

I also tried making a getCurrentTab function that loops through the tabs array and returns the tab name but then I get some weird void is not a string error…

Can anyone help me in the right direction?

Heres the code sandbox:

https://codesandbox.io/p/sandbox/little-water-fyx9w8?file=%2Fsrc%2Fmain.js&selection=%5B%7B%22endColumn%22%3A22%2C%22endLineNumber%22%3A2%2C%22startColumn%22%3A22%2C%22startLineNumber%22%3A2%7D%5D

2

Answers


  1. Update

    Was answered in my other question.

    Solution for the for the <script setup>

    <script setup>
    ...
    </script>
    <script>
       export default {
          icon: 'home-icon',
          name: 'Home'
      }
    </script>
    

    Just put all the tab properties inside your components

    <template>
      <div class="tab">
        Home component
      </div>
    </template>
    <script>
      export default {
          name: 'Home',
          icon: 'house-fill'
      }
    </script>
    

    And then

    <button
       v-for="(tabObj, tab, index) in tabs" 
       :key="tab"
       :class="['tab-button', { active: currentTab === tab }]"
       @click="currentTab = tab"
     >
      icon: {{tabObj.icon}}, name: {{ tabObj.name }}
    </button>
    

    Here is the updated SFC Playground

    Login or Signup to reply.
  2. your idea of ​​tabs is array is correct you just need to add components to them and then refer them to <component />:

    const tabs = [
      { name: 'Home', component: Home, icon: 'house-fill', translation: i18n('message')} ,
      { name: 'Contact', component: Contact, icon: 'telephone-fill', translation: i18n('message')} ,
      { name: 'AboutMe', component: AboutMe, icon: 'person-fill', translation: i18n('message')} ,
    ]
    

    and

    <component :is="tabs[currentTab].component" />
    

    for v-for above also need modification like when you convert tabs to array

    Resolve your example

    your minimal reproducible example is different from the code you provided i don’t understand why you do but you will have to port your own as they are different

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search