diff --git a/apps/web-naive/src/components/description/description.vue b/apps/web-naive/src/components/description/description.vue
index ef0239933..51f0df4d3 100644
--- a/apps/web-naive/src/components/description/description.vue
+++ b/apps/web-naive/src/components/description/description.vue
@@ -1,80 +1,198 @@
diff --git a/apps/web-naive/src/components/description/typing.ts b/apps/web-naive/src/components/description/typing.ts
index 7aadf72dd..9ee489678 100644
--- a/apps/web-naive/src/components/description/typing.ts
+++ b/apps/web-naive/src/components/description/typing.ts
@@ -1,27 +1,41 @@
-import type { DescriptionsProps } from 'naive-ui';
+import type { DescriptionsProps as NDescriptionsProps } from 'naive-ui';
+import type { JSX } from 'vue/jsx-runtime';
import type { CSSProperties, VNode } from 'vue';
-// TODO @xingyu:【content】这个纠结下;1)vben2.0 是 render;https://doc.vvbin.cn/components/desc.html#usage 2)
-// TODO @xingyu:vben2.0 还有 sapn【done】、labelMinWidth、contentMinWidth
-// TODO @xingyu:【hidden】这个纠结下;1)vben2.0 是 show;
+import type { Recordable } from '@vben/types';
+
export interface DescriptionItemSchema {
- label: string | VNode; // 内容的描述
- field?: string; // 对应 data 中的字段名
- content?: ((data: any) => string | VNode) | string | VNode; // 自定义需要展示的内容,比如说 dict-tag
- span?: number; // 包含列的数量
- labelStyle?: CSSProperties; // 自定义标签样式
- contentStyle?: CSSProperties; // 自定义内容样式
- hidden?: ((data: any) => boolean) | boolean; // 是否显示
+ labelMinWidth?: number;
+ contentMinWidth?: number;
+ // 自定义标签样式
+ labelStyle?: CSSProperties;
+ // 对应 data 中的字段名
+ field: string;
+ // 内容的描述
+ label: JSX.Element | string | VNode;
+ // 包含列的数量
+ span?: number;
+ // 是否显示
+ show?: (...arg: any) => boolean;
+ // 插槽名称
+ slot?: string;
+ // 自定义需要展示的内容
+ render?: (
+ val: any,
+ data?: Recordable,
+ ) => Element | JSX.Element | number | string | undefined | VNode;
}
-// TODO @xingyu:vben2.0 还有 title【done】、bordered【done】d、useCollapse、collapseOptions
-// TODO @xingyu:from 5.0:bordered 默认为 true
-// TODO @xingyu:from 5.0:column 默认为 lg: 3, md: 3, sm: 2, xl: 3, xs: 1, xxl: 4
-// TODO @xingyu:from 5.0:size 默认为 small;有 'default', 'middle', 'small', undefined
-// TODO @xingyu:from 5.0:useCollapse 默认为 true
-export interface DescriptionsOptions {
- data?: Record; // 数据
- schema?: DescriptionItemSchema[]; // 描述项配置
- componentProps?: DescriptionsProps; // antd Descriptions 组件参数
+export interface DescriptionProps extends NDescriptionsProps {
+ // 是否包含卡片组件
+ useCard?: boolean;
+ // 描述项配置
+ schema: DescriptionItemSchema[];
+ // 数据
+ data: Recordable;
+}
+
+export interface DescInstance {
+ setDescProps(descProps: Partial): void;
}
diff --git a/apps/web-naive/src/components/description/use-description.ts b/apps/web-naive/src/components/description/use-description.ts
index 7f99238bf..fd24920f0 100644
--- a/apps/web-naive/src/components/description/use-description.ts
+++ b/apps/web-naive/src/components/description/use-description.ts
@@ -1,71 +1,31 @@
-import type { DescriptionsOptions } from './typing';
+import type { Component } from 'vue';
-import { defineComponent, h, isReactive, reactive, watch } from 'vue';
+import type { DescInstance, DescriptionProps } from './typing';
+
+import { h, reactive } from 'vue';
import Description from './description.vue';
-/** 描述列表 api 定义 */
-class DescriptionApi {
- private state = reactive>({});
+export function useDescription(options?: Partial) {
+ const propsState = reactive>(options || {});
- constructor(options: DescriptionsOptions) {
- this.state = { ...options };
- }
+ const api: DescInstance = {
+ setDescProps: (descProps: Partial): void => {
+ Object.assign(propsState, descProps);
+ },
+ };
- getState(): DescriptionsOptions {
- return this.state as DescriptionsOptions;
- }
-
- // TODO @xingyu:【setState】纠结下:1)vben2.0 是 data https://doc.vvbin.cn/components/desc.html#usage;
- setState(newState: Partial) {
- this.state = { ...this.state, ...newState };
- }
-}
-
-export type ExtendedDescriptionApi = DescriptionApi;
-
-export function useDescription(options: DescriptionsOptions) {
- const IS_REACTIVE = isReactive(options);
- const api = new DescriptionApi(options);
- // 扩展 API
- const extendedApi: ExtendedDescriptionApi = api as never;
- const Desc = defineComponent({
+ // 创建一个包装组件,将 propsState 合并到 props 中
+ const DescriptionWrapper: Component = {
name: 'UseDescription',
inheritAttrs: false,
- setup(_, { attrs, slots }) {
- // 合并props和attrs到state
- api.setState({ ...attrs });
-
- return () =>
- h(
- Description,
- {
- ...api.getState(),
- ...attrs,
- },
- slots,
- );
+ setup(_props, { attrs, slots }) {
+ return () => {
+ // @ts-ignore - 避免类型实例化过深
+ return h(Description, { ...propsState, ...attrs }, slots);
+ };
},
- });
+ };
- // 响应式支持
- if (IS_REACTIVE) {
- watch(
- () => options.schema,
- (newSchema) => {
- api.setState({ schema: newSchema });
- },
- { immediate: true, deep: true },
- );
-
- watch(
- () => options.data,
- (newData) => {
- api.setState({ data: newData });
- },
- { immediate: true, deep: true },
- );
- }
-
- return [Desc, extendedApi] as const;
+ return [DescriptionWrapper, api] as const;
}