Bearbeiten
Verwenden Sie die Splitter-Komponente, um eine Liste von Panels anzuzeigen, die durch ziehbare Griffe getrennt sind.
<script setup lang="ts">
import type { SplitterItem } from '@nuxt/ui'
const card = 'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium'
const items: SplitterItem[] = [
{ slot: 'left', minSize: 15, defaultSize: 25, class: card },
{ slot: 'main', minSize: 30, defaultSize: 50, class: card },
{ slot: 'right', minSize: 15, defaultSize: 25, class: card }
]
</script>
<template>
<div class="w-full h-96">
<USplitter id="splitter-example" :items="items">
<template #left>
Left
</template>
<template #main>
Main
</template>
<template #right>
Right
</template>
</USplitter>
</div>
</template>
Items Bearbeiten
Verwenden Sie die items-prop als Array von Objekten mit den folgenden Eigenschaften:
defaultSize?: number(nicht vorhanden)minSize?: number(englisch)maxSize?: number(englisch)collapsible?: boolean(nicht vorhanden)collapsedSize?: number(nicht vorhanden)sizeUnit?: '%' | 'px'(nicht)order?: number(Deutsche Ausgabe)id?: string(nicht)slot?: stringxph0333x (englisch)class?: any(englisch)ui?: { panel?: ClassNameValue }(nicht vorhanden)
Verwenden Sie die slot-Taste, um den Inhalt eines Panels zu füllen und die class-Taste, um es zu stylen. Elemente ohne slot-Taste fallen auf einen panel-{index}-Steckplatz zurück. Größen sind standardmäßig Prozentwerte, setzen Sie sizeUnit: 'px' für ein Element für Pixelwerte.
id prop und geben Sie defaultSize für alle Elemente oder zu none. IDs werden automatisch generiert, sonst und der Server und der Client können nicht zustimmen, die das Layout auf Hydratation bricht. Ein Element ohne eine defaultSize fällt zurück zu einem gleichen Anteil auf dem Server, so dass das Mischen der beiden macht Panels springen einmal hydratisiert. Pixelgrößen werden auf dem Client gemessen und immer ein wenig verschieben.<script setup lang="ts">
import type { SplitterItem } from '@nuxt/ui'
const items = ref<SplitterItem[]>([
{
slot: 'sidebar',
minSize: 15,
maxSize: 40,
defaultSize: 25,
class:
'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium'
},
{
slot: 'main',
defaultSize: 75,
class:
'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium'
}
])
</script>
<template>
<USplitter id="splitter-items" :items="items">
<template #sidebar> Sidebar </template>
<template #main> Main </template>
</USplitter>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { SplitterItem } from '@nuxt/ui'
const items = ref<SplitterItem[]>([
{
slot: 'sidebar',
minSize: 15,
maxSize: 40,
defaultSize: 25,
class:
'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium'
},
{
slot: 'main',
defaultSize: 75,
class:
'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium'
}
])
</script>
<template>
<USplitter id="splitter-items" :items="items">
<template #sidebar> Sidebar </template>
<template #main> Main </template>
</USplitter>
</template>Orientierung
Verwenden Sie die orientation-Stütze, um die Richtung des Splitters zu ändern. Standardmäßig ist horizontal.
<script setup lang="ts">
import type { SplitterItem } from '@nuxt/ui'
const items = ref<SplitterItem[]>([
{
slot: 'first',
class:
'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium'
},
{
slot: 'second',
class:
'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium'
}
])
</script>
<template>
<USplitter id="splitter-orientation" orientation="vertical" :items="items">
<template #first> First </template>
<template #second> Second </template>
</USplitter>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { SplitterItem } from '@nuxt/ui'
const items = ref<SplitterItem[]>([
{
slot: 'first',
class:
'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium'
},
{
slot: 'second',
class:
'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium'
}
])
</script>
<template>
<USplitter id="splitter-orientation" orientation="vertical" :items="items">
<template #first> First </template>
<template #second> Second </template>
</USplitter>
</template>Beispiele
Mit zusammenklappbaren Panel
Setzen Sie collapsible: true auf ein Element, damit es an seinem minSize vorbeibricht, und verwenden Sie collapsedSize, um einen Teil des Panels sichtbar zu halten, wenn es zusammengeklappt wird. Der Panel-Slot macht collapsed, collapse und expand sichtbar, damit Sie es programmgesteuert steuern können, und die Ereignisse collapse, expand und resize werden mit dem Panel-Index ausgelöst.
<script setup lang="ts">
import type { SplitterItem } from '@nuxt/ui'
const items: SplitterItem[] = [
{ slot: 'sidebar', sizeUnit: 'px', minSize: 150, defaultSize: 250, collapsible: true, collapsedSize: 48, class: 'bg-elevated/50 border border-default rounded-xl' },
{ slot: 'main', class: 'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium' }
]
</script>
<template>
<div class="w-full h-96">
<USplitter id="splitter-collapsible-example" :items="items">
<template #sidebar="{ collapsed, collapse, expand }">
<div class="flex-1 flex items-center justify-center p-2">
<UButton
:icon="collapsed ? 'i-lucide-panel-left-open' : 'i-lucide-panel-left-close'"
:label="collapsed ? undefined : 'Collapse'"
:aria-label="collapsed ? 'Expand' : undefined"
color="neutral"
variant="subtle"
@click="collapsed ? expand() : collapse()"
/>
</div>
</template>
<template #main>
Main
</template>
</USplitter>
</div>
</template>
Mit verschachtelten Splittern
Verschachteln Sie einen Splitter in einem Panel, um zweidimensionale Layouts im IDE-Stil zu erstellen.
<script setup lang="ts">
import type { SplitterItem } from '@nuxt/ui'
const card = 'bg-elevated/50 border border-default rounded-xl items-center justify-center text-muted font-medium'
const items: SplitterItem[] = [
{ slot: 'left', minSize: 20, class: card },
{ slot: 'right', minSize: 20 }
]
const nested: SplitterItem[] = [
{ slot: 'top', minSize: 20, class: card },
{ slot: 'bottom', minSize: 20, class: card }
]
</script>
<template>
<div class="w-full h-96">
<USplitter id="splitter-nested-example" :items="items">
<template #left>
Left
</template>
<template #right>
<USplitter id="splitter-nested-example-inner" orientation="vertical" :items="nested">
<template #top>
Top
</template>
<template #bottom>
Bottom
</template>
</USplitter>
</template>
</USplitter>
</div>
</template>
Mit benutzerdefiniertem Griff
Verwenden Sie die ui-Stütze, um sie neu zu gestalten, z. B. als sichtbare Trennwand für bündige Layouts, und den resize-handle-Steckplatz, um Inhalte darin wie einen Griff darzustellen.
<script setup lang="ts">
import type { SplitterItem } from '@nuxt/ui'
const items: SplitterItem[] = [
{ slot: 'left', minSize: 20, defaultSize: 30, class: 'items-center justify-center text-muted font-medium' },
{ slot: 'right', defaultSize: 70, class: 'items-center justify-center text-muted font-medium' }
]
</script>
<template>
<div class="w-full h-96">
<USplitter id="splitter-custom-handle-example" :items="items" :ui="{ handle: 'data-[orientation=horizontal]:w-px data-[orientation=vertical]:h-px bg-border transition-colors data-[state=hover]:bg-primary data-[state=drag]:bg-primary' }" class="rounded-lg border border-default overflow-hidden">
<template #left>
Left
</template>
<template #right>
Right
</template>
</USplitter>
</div>
</template>
With Persistenz
Geben Sie ein auto-save-id ein, um das Layout auf localStorage zu erhalten und beim Neuladen wiederherzustellen.
<template>
<USplitter id="my-layout" auto-save-id="my-layout" :items="items">
<!-- ... -->
</USplitter>
</template>
API Bearbeiten
Props Bearbeiten
| Prop | Default | Type |
|---|---|---|
as | 'div' | anyThe element or component this component should render as. |
id | stringA unique id for the group, also used to derive the ids of its panels and handles. Set it when rendering on the server, auto-generated ids can differ between the server and the client and break resizing on hydration. | |
orientation | 'horizontal' | "horizontal" | "vertical"The orientation of the splitter. |
items | T[] | |
disabled | false | boolean Whether the resize handles are disabled, locking the current layout. |
autoSaveId | null | stringUnique id used to auto-save group arrangement via | |
keyboardResizeBy | null | numberStep size when arrow key was pressed. | |
storage | PanelGroupStorageCustom storage API; defaults to localStorage | |
hitAreaMargins | PointerHitAreaMarginsAllow this much margin when determining resizable handle hit detection | |
ui | { root?: SlotClass; panel?: SlotClass; handle?: SlotClass; } |
Slots Bearbeiten
| Slot | Type |
|---|---|
resize-handle | { index: number; ui: object; } |
Emits (englisch)
| Event | Type |
|---|---|
layout | [val: number[]] |
collapse | [index: number] |
expand | [index: number] |
resize | [index: number, size: number, prevSize?: number | undefined] |
dragging | [index: number, dragging: boolean] |
Theme Bearbeiten
export default defineAppConfig({
ui: {
splitter: {
slots: {
root: '',
panel: 'flex',
handle: 'group relative shrink-0 focus-visible:outline-2 focus-visible:outline-primary data-[panel-resize-handle-enabled=false]:cursor-default'
},
variants: {
orientation: {
horizontal: {
handle: 'w-2 cursor-col-resize'
},
vertical: {
handle: 'h-2 cursor-row-resize'
}
}
}
}
}
})import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
splitter: {
slots: {
root: '',
panel: 'flex',
handle: 'group relative shrink-0 focus-visible:outline-2 focus-visible:outline-primary data-[panel-resize-handle-enabled=false]:cursor-default'
},
variants: {
orientation: {
horizontal: {
handle: 'w-2 cursor-col-resize'
},
vertical: {
handle: 'h-2 cursor-row-resize'
}
}
}
}
}
})
]
})