CnTab
One panel inside a CnTabs strip. Its title is rendered by the parent's nav; its body is rendered in the parent's panel area.
Usage
<CnTabs aria-label="Case details">
<CnTab title="Documents">
<DocumentList />
</CnTab>
<!-- controlled selection -->
<CnTab title="Tasks" :active="tab === 'tasks'" @click="tab = 'tasks'">
<TaskList />
</CnTab>
<!-- rich title -->
<CnTab>
<template #title>
{{ label }} <NcButton variant="tertiary" @click.stop="close()">×</NcButton>
</template>
<DraftForm />
</CnTab>
<CnTab title="Archive" disabled />
</CnTabs>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
title | String | '' | Plain-text tab title. Ignored when a #title slot is supplied. |
active | Boolean | false | Select this tab. Honoured on mount and on every later change, so it can drive a controlled strip. |
disabled | Boolean | false | Render the nav button disabled, skip the tab in keyboard navigation, and never give it the initial selection. |
lazy | Boolean | false | Hold the panel body back until this tab is first activated, then keep it mounted. For strips whose panels are expensive to mount. |
Slots
| Slot | Description |
|---|---|
default | The panel body. |
title | Rich tab title, rendered inside the parent's nav button. Overrides title. Use @click.stop on anything interactive here so it does not also switch tabs. |
Events
| Event | Payload | Description |
|---|---|---|
click | — | The user activated this tab. Fires on click and on keyboard activation. |
Notes
- The panel is not destroyed when inactive. It is hidden with
hidden+display: none, matching bootstrap-vue's<BTab>. A panel that fetches onmounted()would refire that request on every tab switch under av-ifimplementation. Put av-ifinside the panel if you want teardown. lazychanges only the first paint. The body waits until the tab is first activated, and from then on the panel behaves exactly as above: it stays mounted, so switching back never refetches. Reach for it when the panels are expensive. Six panels that each fetch onmounted()fire six requests on page load, and five of them answer questions nobody has asked yet.- A title that is a computed value stays reactive. The parent invokes the child's title renderer inside its own render effect, so the nav strip re-renders when the title changes.
- Rendered outside a
CnTabsparent, the panel shows its content rather than vanishing. The realistic cause of a missedinject()is the package being loaded twice (ADR-019 / openregister#1958), and rendering blank with no error is the worse failure. The injection key is aSymbol.for, so duplicate module instances converge on the same key.
Reference
Props
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
title | string | '' | Plain-text tab title. Ignored when a #title slot is supplied. | |
active | boolean | false | Select this tab. Honoured on mount and on every later change. | |
disabled | boolean | false | Render the nav button disabled and skip this tab in keyboard navigation. | |
lazy | boolean | false | Hold the panel body back until this tab is first activated, then keep it mounted for the rest of the strip's life. Off by default, because the eager panel is what makes a tab switch instant and it is the behaviour every existing consumer already has. Turn it on when the panels are expensive: six panels that each fetch on mounted() fire six requests on page load, and five of those answer questions nobody has asked yet. This is NOT v-if-per-switch. Once a panel has been shown it stays in the DOM, so switching back to it never refetches. That is the whole reason an inactive panel is hidden rather than destroyed. |
Events
| Name | Payload | Description |
|---|---|---|
click | — | The user activated this tab. |
Slots
| Name | Bindings | Description |
|---|---|---|
default | — | The panel body. |
See also
CnTabs— the strip, including the bootstrap-vue migration table