重命名CubeListPager和CubeListToolbarSearch
Yann authored at 2025-07-28 22:53:20 Yann committed at 2025-07-28 23:04:14
3.21 KiB
cube-front
<script setup lang="ts">
import { inject, provide, defineAsyncComponent, useRoute } from 'vue';
import type { Component } from 'vue';
import {
  FormPageHeaderKey,
  FormContentKey,
  FormActionsKey,
  PageSectionRegistryKey,
  SectionKeyMap,
} from '@core/composables/useSections';

import DefaultFormPageHeader from '@core/views/components/FormPageHeader.vue';
import DefaultFormContent from '@core/views/components/FormContent.vue';
import DefaultFormActions from '@core/views/components/FormActions.vue';

interface FormField {
  key: string;
  label: string;
  type: 'text' | 'email' | 'tel' | 'select' | 'textarea' | 'radio';
  required?: boolean;
  fullWidth?: boolean;
  placeholder?: string;
  options?: Array<{ value: string; label: string }>;
  error?: string;
}

interface Props {
  title?: string;
  subtitle?: string;
  fields?: FormField[];
  modelValue?: Record<string, unknown>;
  showContinue?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  showContinue: true,
});

const emit = defineEmits<{
  submit: [];
  continue: [];
  cancel: [];
  'update:modelValue': [val: Record<string, unknown>];
}>();

// ─── 约定式自动发现 ───────────────────────────────────────────────
const route = useRoute();
const registry = inject(
  PageSectionRegistryKey,
  {} as Record<string, Record<string, () => Promise<{ default: unknown }>>>,
);
const pageOverrides = registry[route.path] ?? {};

for (const [name, loader] of Object.entries(pageOverrides)) {
  const key = SectionKeyMap[name];
  if (key) {
    provide(key, defineAsyncComponent(loader as () => Promise<{ default: Component }>));
  }
}

// ─── inject 回退到框架默认 ────────────────────────────────────────
const PageHeaderComp = inject(FormPageHeaderKey, DefaultFormPageHeader);
const FormContentComp = inject(FormContentKey, DefaultFormContent);
const FormActionsComp = inject(FormActionsKey, DefaultFormActions);
</script>

<template>
  <div class="form-page">
    <!-- 页头 -->
    <slot name="header">
      <component :is="PageHeaderComp" :title="title" :subtitle="subtitle" />
    </slot>

    <div class="fp-body">
      <!-- 表单内容 -->
      <slot name="form">
        <component
          :is="FormContentComp"
          :fields="fields"
          :model-value="modelValue"
          @update:model-value="emit('update:modelValue', $event)"
        />
      </slot>

      <!-- 操作区 -->
      <slot name="actions">
        <component
          :is="FormActionsComp"
          :show-continue="showContinue"
          @submit="emit('submit')"
          @continue="emit('continue')"
          @cancel="emit('cancel')"
        />
      </slot>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.form-page {
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.fp-body {
  flex: 1;
  overflow-y: auto;
  padding: 20px 24px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  background: var(--bg);

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-thumb {
    background: #c8d4c8;
    border-radius: 3px;
  }
}
</style>