123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- <script lang="ts" setup>
- import type { ColPageProps } from './types';
- import { computed, ref, useSlots } from 'vue';
- import {
- ResizableHandle,
- ResizablePanel,
- ResizablePanelGroup,
- } from '@vben-core/shadcn-ui';
- import Page from '../page/page.vue';
- defineOptions({
- name: 'ColPage',
- inheritAttrs: false,
- });
- const props = withDefaults(defineProps<ColPageProps>(), {
- leftWidth: 30,
- rightWidth: 70,
- resizable: true,
- });
- const delegatedProps = computed(() => {
- const { leftWidth: _, ...delegated } = props;
- return delegated;
- });
- const slots = useSlots();
- const delegatedSlots = computed(() => {
- const resultSlots: string[] = [];
- for (const key of Object.keys(slots)) {
- if (!['default', 'left'].includes(key)) {
- resultSlots.push(key);
- }
- }
- return resultSlots;
- });
- const leftPanelRef = ref<InstanceType<typeof ResizablePanel>>();
- function expandLeft() {
- leftPanelRef.value?.expand();
- }
- function collapseLeft() {
- leftPanelRef.value?.collapse();
- }
- defineExpose({
- expandLeft,
- collapseLeft,
- });
- </script>
- <template>
- <Page v-bind="delegatedProps">
- <!-- 继承默认的slot -->
- <template
- v-for="slotName in delegatedSlots"
- :key="slotName"
- #[slotName]="slotProps"
- >
- <slot :name="slotName" v-bind="slotProps"></slot>
- </template>
- <ResizablePanelGroup class="w-full" direction="horizontal">
- <ResizablePanel
- ref="leftPanelRef"
- :collapsed-size="leftCollapsedWidth"
- :collapsible="leftCollapsible"
- :default-size="leftWidth"
- :max-size="leftMaxWidth"
- :min-size="leftMinWidth"
- >
- <template #default="slotProps">
- <slot
- name="left"
- v-bind="{
- ...slotProps,
- expand: expandLeft,
- collapse: collapseLeft,
- }"
- ></slot>
- </template>
- </ResizablePanel>
- <ResizableHandle
- v-if="resizable"
- :style="{ backgroundColor: splitLine ? undefined : 'transparent' }"
- :with-handle="splitHandle"
- />
- <ResizablePanel
- :collapsed-size="rightCollapsedWidth"
- :collapsible="rightCollapsible"
- :default-size="rightWidth"
- :max-size="rightMaxWidth"
- :min-size="rightMinWidth"
- >
- <template #default>
- <slot></slot>
- </template>
- </ResizablePanel>
- </ResizablePanelGroup>
- </Page>
- </template>
|