Jacobs63/vue3-tabs-component

All tabs contents are showing for some milliseconds

Closed this issue · 3 comments

Hello,

Right now, while reloading the page, all tabs contents are showing for some milliseconds, and then the inactive tabs will receive display none and everything looks like it should.

In a large app, this problem is real and very annoying. In your demo everything works great.
Any idea on how should I fix this problem ?

This is how i implemented:

<tabs ref="tabsRef" :options="{ defaultTabHash: 'security' }" :cache-lifetime="-1" wrapper-class="tab-content">
    <tab id="profile" name="Profile" panel-class="tab-pane">...</tab>
    <tab id="security" name="Security" panel-class="tab-pane">...</tab>
    <tab id="emails" name="Emails" panel-class="tab-pane">...</tab>
</tabs>

Demo:

vue-3-tabs-problem

I managed to fix it by wrapping all the tabs content into a div with display: none and v-show when activeTab is set.

<tabs ref="tabsRef" :options="{ defaultTabHash: 'security' }" :cache-lifetime="-1" wrapper-class="tab-content">
    <tab id="profile" name="Profile" panel-class="tab-pane">
        <div class="tab-wrapper" style="display: none" v-show="activeTabShowed">
            <!-- tab content here -->
        </div>
    </tab>
    <!-- more tabs here -->
</tabs>
const tabsRef = ref(null);
const activeTab = computed(() => tabsRef.value ? tabsRef.value.activeTabHash : null);
const activeTabShowed = computed(() => activeTab.value === null ? false : true);

Hello,

it's definitely possible that once multiple tabs are being initialized, which might contain a lot of additional content/components, there might be a visible delay until the mounting process is completed.

I'd definitely go with hiding everything by-default, preferably adding some sort of loading class, then once the tabs component is mounted, just remove the loading class.

It might be possible to do this in the package by-default - render all tabs as display: none; immediately, I'll take a look, hopefully, this weekend.

Final version:

<div class="tabs-wrapper" style="display: none;" v-show="activeTabShowed">
    <tabs ref="tabsRef" :options="{ defaultTabHash: 'security' }" :cache-lifetime="-1" wrapper-class="tab-content">
        <tab id="profile" name="Profile" panel-class="tab-pane">...</tab>
        <tab id="security" name="Security" panel-class="tab-pane">...</tab>
        <tab id="emails" name="Emails" panel-class="tab-pane">...</tab>
    </tabs>
</div>
const tabsRef = ref(null);
const activeTab = computed(() => tabsRef.value ? tabsRef.value.activeTabHash : null);
const activeTabShowed = computed(() => activeTab.value === null ? false : true);

The activeTab ref was created because i have a custom tabs navigation.
Works great now.