@qin-ui/antd-vue-pro 2.4.5 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI-CONTEXT.md +26 -2
- package/README.md +44 -37
- package/api.json +24 -9
- package/es/antd-vue-pro.css +15 -15
- package/es/components/component-provider/components/index.vue.d.ts +3 -3
- package/es/components/component-provider/components/index.vue.d.ts.map +1 -1
- package/es/components/component-provider/constants/index.d.ts +20 -4
- package/es/components/component-provider/constants/index.d.ts.map +1 -1
- package/es/components/component-provider/types/index.d.ts +7 -3
- package/es/components/component-provider/types/index.d.ts.map +1 -1
- package/es/components/form/components/BaseField/index.vue.d.ts +7 -1
- package/es/components/form/components/BaseField/index.vue.d.ts.map +1 -1
- package/es/components/form/components/BaseField/utils/index.d.ts +18 -0
- package/es/components/form/components/BaseField/utils/index.d.ts.map +1 -1
- package/es/components/form/components/BaseFormItem/index.vue.d.ts +3 -0
- package/es/components/form/components/BaseFormItem/index.vue.d.ts.map +1 -1
- package/es/components/form/components/ContainerFragment/index.vue.d.ts +1 -0
- package/es/components/form/components/ContainerFragment/index.vue.d.ts.map +1 -1
- package/es/components/form/components/ProForm/index.vue.d.ts.map +1 -1
- package/es/components/form/components/SlotComponent/index.vue.d.ts +1 -0
- package/es/components/form/components/SlotComponent/index.vue.d.ts.map +1 -1
- package/es/components/form/components/index.d.ts +4 -0
- package/es/components/form/components/index.d.ts.map +1 -1
- package/es/components/form/constants/index.d.ts.map +1 -1
- package/es/components/form/hooks/useFields.d.ts +2 -0
- package/es/components/form/hooks/useFields.d.ts.map +1 -1
- package/es/components/form/hooks/useGroupFieldAttrs.d.ts +10 -0
- package/es/components/form/hooks/useGroupFieldAttrs.d.ts.map +1 -1
- package/es/components/form/index.d.ts +2 -2
- package/es/components/form/index.d.ts.map +1 -1
- package/es/components/form/types/index.d.ts +75 -44
- package/es/components/form/types/index.d.ts.map +1 -1
- package/es/components/form/utils/fieldKey.d.ts +13 -0
- package/es/components/form/utils/fieldKey.d.ts.map +1 -0
- package/es/components/table/components/ColumnControl.vue.d.ts +3 -0
- package/es/components/table/components/ColumnControl.vue.d.ts.map +1 -1
- package/es/components/table/components/DefaultSearchFormContainer.vue.d.ts.map +1 -1
- package/es/components/table/components/DefaultTableContainer.vue.d.ts.map +1 -1
- package/es/components/table/components/ProTable.vue.d.ts +8 -1
- package/es/components/table/components/ProTable.vue.d.ts.map +1 -1
- package/es/components/table/components/SearchForm.vue.d.ts +9 -1
- package/es/components/table/components/SearchForm.vue.d.ts.map +1 -1
- package/es/components/table/components/SizeControl.vue.d.ts +7 -2
- package/es/components/table/components/SizeControl.vue.d.ts.map +1 -1
- package/es/components/table/hooks/useTable.d.ts.map +1 -1
- package/es/components/table/index.d.ts +4 -1
- package/es/components/table/index.d.ts.map +1 -1
- package/es/components/table/types/index.d.ts +14 -6
- package/es/components/table/types/index.d.ts.map +1 -1
- package/es/index.d.ts +8 -4
- package/es/index.d.ts.map +1 -1
- package/es/index.js +259 -123
- package/es/index.js.map +1 -1
- package/es/locale/index.d.ts +2 -0
- package/es/locale/index.d.ts.map +1 -1
- package/es/shared/core/index.d.ts +1 -1
- package/es/shared/core/index.d.ts.map +1 -1
- package/es/shared/ui/index.d.ts +15 -3
- package/es/shared/ui/index.d.ts.map +1 -1
- package/package.json +5 -3
- package/src/components/component-provider/components/index.vue +26 -12
- package/src/components/component-provider/constants/index.ts +33 -6
- package/src/components/component-provider/types/index.ts +17 -9
- package/src/components/form/components/BaseField/index.vue +41 -13
- package/src/components/form/components/BaseField/utils/index.ts +19 -1
- package/src/components/form/components/BaseFormItem/index.vue +28 -30
- package/src/components/form/components/ContainerFragment/index.vue +3 -1
- package/src/components/form/components/ProForm/index.vue +19 -14
- package/src/components/form/components/SlotComponent/index.vue +14 -4
- package/src/components/form/components/index.ts +8 -1
- package/src/components/form/constants/index.ts +3 -4
- package/src/components/form/hooks/useFields.ts +3 -1
- package/src/components/form/hooks/useGroupFieldAttrs.ts +29 -13
- package/src/components/form/index.ts +1 -3
- package/src/components/form/types/index.ts +79 -46
- package/src/components/form/utils/fieldKey.ts +27 -0
- package/src/components/table/components/ColumnControl.vue +17 -3
- package/src/components/table/components/DefaultSearchFormContainer.vue +5 -0
- package/src/components/table/components/DefaultTableContainer.vue +5 -0
- package/src/components/table/components/ProTable.vue +228 -69
- package/src/components/table/components/SearchForm.vue +56 -19
- package/src/components/table/components/SizeControl.vue +21 -1
- package/src/components/table/hooks/useTable.ts +1 -1
- package/src/components/table/index.ts +8 -3
- package/src/components/table/types/index.ts +15 -7
- package/src/index.ts +12 -5
- package/src/locale/index.ts +2 -0
- package/src/shared/core/index.ts +11 -0
- package/src/shared/ui/index.ts +22 -4
- package/tsconfig.json +0 -1
package/es/locale/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { InjectionKey, MaybeRef } from 'vue';
|
|
2
2
|
import { zhCN, zhTW, enUS, ProLocale, ProLocaleName } from '../shared/core';
|
|
3
|
+
/** 内置语言包:简体中文 / 繁体中文 / 英文 */
|
|
3
4
|
export { zhCN, zhTW, enUS };
|
|
5
|
+
/** 文案表类型:键为内置文案 key,值为任意字符串 */
|
|
4
6
|
export type { ProLocale };
|
|
5
7
|
/** ProComponentProvider 通过该 key 注入局部覆盖文案 */
|
|
6
8
|
export declare const LOCALE_INJECT_KEY: InjectionKey<MaybeRef<Partial<ProLocale> | undefined>>;
|
package/es/locale/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/locale/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,QAAQ,EACd,MAAM,KAAK,CAAC;AACb,OAAO,EACL,IAAI,EACJ,IAAI,EACJ,IAAI,EAGJ,KAAK,SAAS,EACd,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAE5B,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAC1C,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,CAClB,CAAC;AAEzB;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,SAAS;aAWJ,MAAM,WAAW,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAG,MAAM;;CAQ1E,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/locale/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,QAAQ,EACd,MAAM,KAAK,CAAC;AACb,OAAO,EACL,IAAI,EACJ,IAAI,EACJ,IAAI,EAGJ,KAAK,SAAS,EACd,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAC;AAGxB,6BAA6B;AAC7B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAE5B,+BAA+B;AAC/B,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,4CAA4C;AAC5C,eAAO,MAAM,iBAAiB,EAAE,YAAY,CAC1C,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC,CAClB,CAAC;AAEzB;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,SAAS;aAWJ,MAAM,WAAW,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAG,MAAM;;CAQ1E,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 统一 re-export @qin-ui/pro-components-core,包内所有文件通过此文件引入 core 内容。
|
|
3
3
|
*/
|
|
4
|
-
export { useForm, createFormProxy, useTable, useSearchFormExpand, useFields, useFormData, useFormRef, InjectionFormKey, InjectionFormSlotsKey, getObject, get, set, normalizePathKey, toPath, camelizeProperties, cloneDeep, pick, isPlainObject, isPromise, zhCN, zhTW, enUS, format, resolveLocaleName, type ProLocale, type ProLocaleName, type ProLocaleKey, type Data, type Path, type Paths, type KeyExpandString, type ExtendWithAny, type DeepPartial, type PageParam, type Fields, type Form, type Table, type UseFieldsReturn, type UseFormDataReturn, type UseFormRefReturn, } from '@qin-ui/pro-components-core';
|
|
4
|
+
export { type AdditionalMethods, localePacks, normalizeColumn, normalizeColumns, useForm, createFormProxy, useTable, useSearchFormExpand, useFields, resolveFieldIdentity, DEFAULT_FIELD_IDENTITY_KEYS, useFormData, useFormRef, useReactiveAttrs, InjectionFormKey, InjectionFormSlotsKey, getObject, omitBy, get, set, normalizePathKey, toPath, camelizeProperties, cloneDeep, pick, omit, isPlainObject, isObjectItem, isPromise, zhCN, zhTW, enUS, format, resolveLocaleName, type ProLocale, type ProLocaleName, type ProLocaleKey, type Data, type Path, type Paths, type KeyExpandString, type ExtendWithAny, type DeepPartial, type PageParam, type Fields, type Form, type Table, type UseFieldsReturn, type UseFormDataReturn, type UseFormRefReturn, } from '@qin-ui/pro-components-core';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAEL,OAAO,EACP,eAAe,EACf,QAAQ,EACR,mBAAmB,EACnB,SAAS,EACT,WAAW,EACX,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAEL,KAAK,iBAAiB,EACtB,WAAW,EACX,eAAe,EACf,gBAAgB,EAEhB,OAAO,EACP,eAAe,EACf,QAAQ,EACR,mBAAmB,EACnB,SAAS,EACT,oBAAoB,EACpB,2BAA2B,EAC3B,WAAW,EACX,UAAU,EACV,gBAAgB,EAEhB,gBAAgB,EAChB,qBAAqB,EAErB,SAAS,EACT,MAAM,EACN,GAAG,EACH,GAAG,EACH,gBAAgB,EAChB,MAAM,EACN,kBAAkB,EAClB,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,aAAa,EACb,YAAY,EACZ,SAAS,EAET,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,iBAAiB,EACjB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,YAAY,EAEjB,KAAK,IAAI,EACT,KAAK,IAAI,EACT,KAAK,KAAK,EACV,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,IAAI,EACT,KAAK,KAAK,EACV,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,6BAA6B,CAAC"}
|
package/es/shared/ui/index.d.ts
CHANGED
|
@@ -1,15 +1,27 @@
|
|
|
1
|
-
import { FormProps as _FormProps } from 'ant-design-vue';
|
|
1
|
+
import { FormProps as _FormProps, Table, TableProps as _TableProps } from 'ant-design-vue';
|
|
2
|
+
import { ComponentProps } from 'vue-component-type-helpers';
|
|
2
3
|
import { Options } from 'scroll-into-view-if-needed';
|
|
3
|
-
export { theme, Form, FormItem, Row as Grid, Col as GridItem, Table, Space, MenuDivider, Dropdown, Menu, MenuItem, Checkbox, Button, Cascader, CheckboxGroup, DatePicker, Input, InputNumber, InputPassword, InputSearch, RadioGroup, Select, Slider, Switch, Textarea, TimePicker, Transfer, TreeSelect, RangePicker, type FormItemInstance, type FormInstance, type RowProps as GridProps, type ColProps as GridItemProps, type FormItemProps, type
|
|
4
|
+
export { theme, Form, FormItem, Row as Grid, Col as GridItem, Table, Space, MenuDivider, Dropdown, Menu, MenuItem, Checkbox, Button, Cascader, CheckboxGroup, DatePicker, Input, InputNumber, InputPassword, InputSearch, RadioGroup, Select, Slider, Switch, Textarea, TimePicker, Transfer, TreeSelect, RangePicker, type FormItemInstance, type FormInstance, type RowProps as GridProps, type ColProps as GridItemProps, type FormItemProps, type PaginationProps, } from 'ant-design-vue';
|
|
4
5
|
export { type ColumnType, tableProps } from 'ant-design-vue/es/table';
|
|
5
6
|
export { type RangePickerProps } from 'ant-design-vue/es/date-picker';
|
|
6
7
|
export { useConfigContextInject } from 'ant-design-vue/es/config-provider/context';
|
|
7
8
|
export { useInjectDisabled, useProviderDisabled, } from 'ant-design-vue/es/config-provider/DisabledContext';
|
|
8
9
|
export { colProps as gridItemProps } from 'ant-design-vue/es/grid/Col';
|
|
9
|
-
export { formItemProps
|
|
10
|
+
export { formItemProps } from 'ant-design-vue/es/form';
|
|
11
|
+
export { useInjectFormItemContext, useProvideFormItemContext, } from 'ant-design-vue/es/form/FormItemContext';
|
|
10
12
|
export { type NamePath } from 'ant-design-vue/es/form/interface';
|
|
11
13
|
export { type MenuItemType } from 'ant-design-vue/es/menu/src/interface';
|
|
14
|
+
/** 宿主 Form 属性面;`scrollToFirstError` 放宽为布尔或滚动配置对象 */
|
|
12
15
|
export type FormProps = Omit<_FormProps, 'scrollToFirstError'> & {
|
|
13
16
|
scrollToFirstError?: boolean | Options<any>;
|
|
14
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* 表格完整属性面
|
|
20
|
+
*
|
|
21
|
+
* @description 由宿主 `TableProps` 与其未声明的 emit 型属性键组成;
|
|
22
|
+
* ant-design-vue 的 Table 未暴露 `scroll` 事件面,故不提供 `@scroll` 入口。
|
|
23
|
+
*/
|
|
24
|
+
export interface TableProps extends _TableProps {
|
|
25
|
+
'onUpdate:expandedRowKeys'?: ComponentProps<typeof Table>['onUpdate:expandedRowKeys'];
|
|
26
|
+
}
|
|
15
27
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,IAAI,UAAU,EACvB,KAAK,EACL,UAAU,IAAI,WAAW,EAC1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EACL,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,GAAG,IAAI,IAAI,EACX,GAAG,IAAI,QAAQ,EACf,KAAK,EACL,KAAK,EACL,WAAW,EACX,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,aAAa,EACb,UAAU,EACV,KAAK,EACL,WAAW,EACX,aAAa,EACb,WAAW,EACX,UAAU,EACV,MAAM,EACN,MAAM,EACN,MAAM,EACN,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,UAAU,EACV,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,QAAQ,IAAI,SAAS,EAC1B,KAAK,QAAQ,IAAI,aAAa,EAC9B,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AACnF,OAAO,EACL,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,QAAQ,IAAI,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAEzE,oDAAoD;AACpD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,oBAAoB,CAAC,GAAG;IAC/D,kBAAkB,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAC7C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,0BAA0B,CAAC,EAAE,cAAc,CACzC,OAAO,KAAK,CACb,CAAC,0BAA0B,CAAC,CAAC;CAC/B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qin-ui/antd-vue-pro",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "二次封装antd vue组件",
|
|
5
5
|
"bin": {
|
|
6
6
|
"antd-vue-pro": "./bin/init-ai.mjs"
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"types": "./es/index.d.ts",
|
|
15
15
|
"import": "./es/index.js"
|
|
16
16
|
},
|
|
17
|
-
"./antd-vue-pro.css": "./es/antd-vue-pro.css"
|
|
17
|
+
"./antd-vue-pro.css": "./es/antd-vue-pro.css",
|
|
18
|
+
"./package.json": "./package.json"
|
|
18
19
|
},
|
|
19
20
|
"files": [
|
|
20
21
|
"es",
|
|
@@ -44,9 +45,10 @@
|
|
|
44
45
|
"dependencies": {
|
|
45
46
|
"scroll-into-view-if-needed": "^3.1.0",
|
|
46
47
|
"vue-component-type-helpers": "^3.2.5",
|
|
47
|
-
"@qin-ui/pro-components-core": "^2.0
|
|
48
|
+
"@qin-ui/pro-components-core": "^2.1.0"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
51
|
+
"@types/node": "^24",
|
|
50
52
|
"@vue/test-utils": "^2.4.11",
|
|
51
53
|
"ant-design-vue": "^4.2.6",
|
|
52
54
|
"happy-dom": "^20.11.6",
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
/**
|
|
3
|
+
* 全局配置提供者组件
|
|
4
|
+
*
|
|
3
5
|
* @component ProComponentProvider
|
|
4
|
-
* @description @qin-ui/antd-vue-pro 全局配置提供者组件
|
|
5
6
|
* @public
|
|
6
7
|
*
|
|
7
8
|
* 用于在组件树的顶层配置所有子组件的全局默认属性。
|
|
@@ -28,15 +29,16 @@
|
|
|
28
29
|
* </template>
|
|
29
30
|
* ```
|
|
30
31
|
*/
|
|
31
|
-
import { ComponentVars } from '../types';
|
|
32
32
|
import {
|
|
33
|
+
INJECT_COMPONENT_VARS,
|
|
33
34
|
INJECT_COMPONENTS,
|
|
34
35
|
INJECT_CONFIG,
|
|
35
36
|
ensureInjectConfig,
|
|
36
37
|
} from '../constants';
|
|
38
|
+
import type { ComponentVars } from '../types';
|
|
37
39
|
import { computed, provide } from 'vue';
|
|
38
|
-
import { getObject } from '../../../shared/core';
|
|
39
|
-
import { ComponentName } from '../../form/constants';
|
|
40
|
+
import { getObject, omit } from '../../../shared/core';
|
|
41
|
+
import type { ComponentName } from '../../form/constants';
|
|
40
42
|
import { LOCALE_INJECT_KEY, type ProLocale } from '../../../locale';
|
|
41
43
|
|
|
42
44
|
type ComponentMap = Partial<Record<ComponentName, any>>;
|
|
@@ -48,19 +50,19 @@ defineOptions({
|
|
|
48
50
|
|
|
49
51
|
type Props = {
|
|
50
52
|
/**
|
|
51
|
-
*
|
|
53
|
+
* 组件全局配置
|
|
52
54
|
* 可配置所有内置组件和 Pro 组件的默认属性
|
|
53
55
|
* @example { 'input': { placeholder: '请输入' }, 'pro-form': { grid: { gutter: 24 } } }
|
|
54
56
|
*/
|
|
55
57
|
componentVars?: ComponentVars;
|
|
56
58
|
/**
|
|
57
|
-
*
|
|
59
|
+
* 自定义组件映射
|
|
58
60
|
* 用于替换或扩展内置组件,传入的组件会覆盖默认的同名组件
|
|
59
61
|
* @example { 'input': MyCustomInput, 'select': MyCustomSelect }
|
|
60
62
|
*/
|
|
61
63
|
componentMap?: ComponentMap;
|
|
62
64
|
/**
|
|
63
|
-
*
|
|
65
|
+
* 内置文案覆盖
|
|
64
66
|
* 可覆盖任意 locale 文案(如查询/重置/序号/占位符等),
|
|
65
67
|
* 未覆盖的文案默认跟随宿主组件库语言自动切换
|
|
66
68
|
* @example { 'table.query': '搜索' }
|
|
@@ -76,18 +78,24 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
76
78
|
|
|
77
79
|
/*
|
|
78
80
|
* 遍历 componentVars 的每个 key,获取或创建对应的 inject 配置
|
|
79
|
-
*
|
|
81
|
+
* 将用户提供的值合并到默认值上,剔除该注入项的不可注入键后通过 provide 响应式注入到子组件树
|
|
80
82
|
* 子组件通过 inject(config.injectionKey) 获取合并后的计算属性配置
|
|
81
83
|
*/
|
|
82
84
|
(Object.keys(INJECT_CONFIG) as Array<keyof typeof INJECT_CONFIG>).forEach(
|
|
83
85
|
key => {
|
|
84
86
|
const config = INJECT_CONFIG[key];
|
|
87
|
+
const ignored = config.ignoreProps;
|
|
85
88
|
provide(
|
|
86
89
|
config.injectionKey,
|
|
87
|
-
computed(() =>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
computed(() =>
|
|
91
|
+
omit(
|
|
92
|
+
{
|
|
93
|
+
...config.default,
|
|
94
|
+
...getObject(props.componentVars?.[key as keyof ComponentVars]),
|
|
95
|
+
},
|
|
96
|
+
ignored ?? []
|
|
97
|
+
)
|
|
98
|
+
)
|
|
91
99
|
);
|
|
92
100
|
}
|
|
93
101
|
);
|
|
@@ -108,6 +116,12 @@ if (props.componentVars) {
|
|
|
108
116
|
});
|
|
109
117
|
}
|
|
110
118
|
|
|
119
|
+
// 全量 componentVars:自定义组件键在运行期新增后同样可被子组件读取
|
|
120
|
+
provide(
|
|
121
|
+
INJECT_COMPONENT_VARS,
|
|
122
|
+
computed(() => (props.componentVars as Record<string, any>) ?? {})
|
|
123
|
+
);
|
|
124
|
+
|
|
111
125
|
// 注入自定义组件映射,BaseField 在解析组件时会优先使用此映射
|
|
112
126
|
provide(
|
|
113
127
|
INJECT_COMPONENTS,
|
|
@@ -1,28 +1,40 @@
|
|
|
1
|
-
import { RequiredComponentVars } from '../types';
|
|
2
|
-
import { InjectionKey, Component
|
|
1
|
+
import type { RequiredComponentVars } from '../types';
|
|
2
|
+
import type { InjectionKey, Component } from 'vue';
|
|
3
|
+
import { type ComputedRef } from 'vue';
|
|
3
4
|
|
|
4
5
|
const getPopupContainer = (triggerNode: any) =>
|
|
5
6
|
triggerNode.closest?.("form[class*='-form']") ||
|
|
6
7
|
(typeof document !== 'undefined' ? document.body : undefined);
|
|
7
8
|
|
|
9
|
+
/** 自定义组件映射的注入 key:ProComponentProvider 注入,BaseField 解析组件时优先取用 */
|
|
8
10
|
export const INJECT_COMPONENTS: InjectionKey<
|
|
9
11
|
| ComputedRef<Partial<Record<string, Component>> | undefined>
|
|
10
12
|
| Partial<Record<string, Component>>
|
|
11
13
|
> = Symbol('INJECT_COMPONENTS');
|
|
12
14
|
|
|
15
|
+
/** 全量 componentVars 注入通道:运行期新增的自定义组件键由此读取(按组件名取配置) */
|
|
16
|
+
export const INJECT_COMPONENT_VARS: InjectionKey<
|
|
17
|
+
ComputedRef<Record<string, any> | undefined> | Record<string, any>
|
|
18
|
+
> = Symbol('COMPONENT_VARS');
|
|
19
|
+
|
|
20
|
+
/** 单个组件名的注入配置:注入 key、默认值与不接受 Provider 注入的键 */
|
|
13
21
|
export type InjectConfigEntry<T = any> = {
|
|
14
22
|
injectionKey: InjectionKey<T>;
|
|
15
23
|
default: T;
|
|
24
|
+
/** 不接受 Provider 注入的键,注入层静默剔除 */
|
|
25
|
+
ignoreProps?: readonly string[];
|
|
16
26
|
};
|
|
17
27
|
|
|
28
|
+
/** 内置组件名的注入配置表:每个组件名对应一份默认值,Provider 注入值与之合并 */
|
|
18
29
|
export const INJECT_CONFIG: {
|
|
19
|
-
[key in keyof RequiredComponentVars]:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
};
|
|
30
|
+
[key in keyof RequiredComponentVars]: InjectConfigEntry<
|
|
31
|
+
RequiredComponentVars[key]
|
|
32
|
+
>;
|
|
23
33
|
} = {
|
|
24
34
|
'pro-table': {
|
|
25
35
|
injectionKey: Symbol(''),
|
|
36
|
+
// 列 / 数据源取自组件绑定或 `:table` 实例,加载态由组件自身状态驱动
|
|
37
|
+
ignoreProps: ['loading', 'columns', 'dataSource'],
|
|
26
38
|
default: {
|
|
27
39
|
pagination: {
|
|
28
40
|
showSizeChanger: true,
|
|
@@ -39,6 +51,8 @@ export const INJECT_CONFIG: {
|
|
|
39
51
|
},
|
|
40
52
|
'pro-form': {
|
|
41
53
|
injectionKey: Symbol(''),
|
|
54
|
+
// 表单实例由 `:form` 显式传入
|
|
55
|
+
ignoreProps: ['form'],
|
|
42
56
|
default: { grid: { gutter: { xs: 8, sm: 16, md: 16, lg: 24 } } },
|
|
43
57
|
},
|
|
44
58
|
'pro-form-item': {
|
|
@@ -142,9 +156,16 @@ export const INJECT_CONFIG: {
|
|
|
142
156
|
},
|
|
143
157
|
};
|
|
144
158
|
|
|
159
|
+
/** 内置集合之外的组件名经此登记的注入通道,无原型链 */
|
|
145
160
|
const DYNAMIC_INJECT_CONFIG: Record<string, InjectConfigEntry> =
|
|
146
161
|
Object.create(null);
|
|
147
162
|
|
|
163
|
+
/**
|
|
164
|
+
* 按组件名取注入配置
|
|
165
|
+
* @description 先查内置配置表,再查动态登记的通道
|
|
166
|
+
* @param key - 组件名(含 `date-picker.month` 等子类型段)
|
|
167
|
+
* @returns 对应注入配置,未登记时为 `undefined`
|
|
168
|
+
*/
|
|
148
169
|
export const getInjectConfig = (key: string): InjectConfigEntry | undefined => {
|
|
149
170
|
return (
|
|
150
171
|
(INJECT_CONFIG as Record<string, InjectConfigEntry>)[key] ||
|
|
@@ -152,6 +173,12 @@ export const getInjectConfig = (key: string): InjectConfigEntry | undefined => {
|
|
|
152
173
|
);
|
|
153
174
|
};
|
|
154
175
|
|
|
176
|
+
/**
|
|
177
|
+
* 按组件名取注入配置,未登记时补建
|
|
178
|
+
* @description 补建的通道使用独立的 Symbol 注入 key 与空默认值,同一组件名重复调用返回同一配置
|
|
179
|
+
* @param key - 组件名
|
|
180
|
+
* @returns 已存在或新建的注入配置
|
|
181
|
+
*/
|
|
155
182
|
export const ensureInjectConfig = (key: string): InjectConfigEntry => {
|
|
156
183
|
const existing = getInjectConfig(key);
|
|
157
184
|
if (existing) return existing;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import type {
|
|
2
|
+
GridItemProps,
|
|
3
|
+
FormItemProps,
|
|
4
|
+
TableProps,
|
|
5
|
+
} from '../../../shared/ui';
|
|
6
|
+
import type { Base, Grid } from '../../form/types';
|
|
7
|
+
import type { ProFormProps } from '../../form/components';
|
|
8
|
+
import type { ProTableProps } from '../../table';
|
|
9
|
+
import type { AllowedComponentProps } from 'vue';
|
|
6
10
|
|
|
7
|
-
import { GetComponentType, ComponentName } from '../../form/constants';
|
|
11
|
+
import type { GetComponentType, ComponentName } from '../../form/constants';
|
|
8
12
|
import type { ComponentProps } from 'vue-component-type-helpers';
|
|
9
13
|
|
|
10
14
|
type PP<T extends Record<string, any>> = Partial<T & AllowedComponentProps>;
|
|
@@ -16,7 +20,7 @@ type FP<T extends Record<string, any>> = Partial<
|
|
|
16
20
|
>;
|
|
17
21
|
|
|
18
22
|
/**
|
|
19
|
-
*
|
|
23
|
+
* 全局配置变量类型
|
|
20
24
|
*
|
|
21
25
|
* @description 定义可通过 ProComponentProvider 配置的所有组件默认属性。
|
|
22
26
|
* 支持配置表单、表格、表单项以及所有内置组件的默认属性。
|
|
@@ -40,9 +44,13 @@ type FP<T extends Record<string, any>> = Partial<
|
|
|
40
44
|
* ```
|
|
41
45
|
*/
|
|
42
46
|
export type RequiredComponentVars = {
|
|
43
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* ProTable 全局默认属性
|
|
49
|
+
*
|
|
50
|
+
* @description `columns` / `dataSource` / `loading` 不参与全局注入:三者分别由 `:table` 实例(`useTable`)与组件自身查询状态驱动。
|
|
51
|
+
*/
|
|
44
52
|
'pro-table': PP<
|
|
45
|
-
TableProps &
|
|
53
|
+
Omit<TableProps, 'loading' | 'columns' | 'dataSource'> &
|
|
46
54
|
Pick<
|
|
47
55
|
ProTableProps,
|
|
48
56
|
| 'control'
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
/**
|
|
3
|
+
* 字段级渲染组件,负责将 field 配置渲染为实际的输入组件
|
|
4
|
+
*
|
|
3
5
|
* @component BaseField
|
|
4
|
-
* @description 字段级渲染组件,负责将 field 配置渲染为实际的输入组件
|
|
5
6
|
*
|
|
6
7
|
* ## 核心职责
|
|
7
8
|
*
|
|
@@ -34,18 +35,23 @@ import {
|
|
|
34
35
|
mergeProps,
|
|
35
36
|
ref,
|
|
36
37
|
toValue,
|
|
37
|
-
useAttrs,
|
|
38
38
|
} from 'vue';
|
|
39
|
-
import {
|
|
39
|
+
import {
|
|
40
|
+
cloneDeep,
|
|
41
|
+
getObject,
|
|
42
|
+
useReactiveAttrs,
|
|
43
|
+
} from '../../../../shared/core';
|
|
40
44
|
import {
|
|
41
45
|
useInjectDisabled,
|
|
42
46
|
useInjectFormItemContext,
|
|
47
|
+
useProvideFormItemContext,
|
|
43
48
|
} from '../../../../shared/ui';
|
|
44
49
|
import type { Field } from '../../types';
|
|
45
50
|
import ContainerFragment from '../ContainerFragment/index.vue';
|
|
46
51
|
import SlotComponent from '../SlotComponent/index.vue';
|
|
47
52
|
import { componentMap, InjectionFormSlotsKey } from '../../constants';
|
|
48
53
|
import {
|
|
54
|
+
INJECT_COMPONENT_VARS,
|
|
49
55
|
INJECT_COMPONENTS,
|
|
50
56
|
getInjectConfig,
|
|
51
57
|
} from '../../../component-provider/constants';
|
|
@@ -60,7 +66,9 @@ const cloneDeepIfObject = (val: unknown) =>
|
|
|
60
66
|
defineOptions({ name: 'BaseField', inheritAttrs: false });
|
|
61
67
|
|
|
62
68
|
type Props = {
|
|
69
|
+
/** 组件名或组件对象 */
|
|
63
70
|
component?: string | Component;
|
|
71
|
+
/** 字段路径,用于绑定表单数据 */
|
|
64
72
|
path?: string;
|
|
65
73
|
};
|
|
66
74
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -74,12 +82,29 @@ const form = useForm(false);
|
|
|
74
82
|
|
|
75
83
|
const componentRef = ref<any>();
|
|
76
84
|
|
|
85
|
+
const emit = defineEmits<{
|
|
86
|
+
(e: 'field-value-change', value: unknown): void;
|
|
87
|
+
}>();
|
|
88
|
+
|
|
89
|
+
/*
|
|
90
|
+
* 派生 FormItem 校验上下文:保留父级 id、clearValidate 与 blur 通路,变更回调置空。
|
|
91
|
+
* 控件(含包装组件内部与插槽内的宿主控件)的值变更统一经字段事件回传一次,
|
|
92
|
+
* 不在宿主上下文内自报,避免同一字段同一 tick 触发两遍校验
|
|
93
|
+
*/
|
|
77
94
|
const formItemContext = useInjectFormItemContext();
|
|
78
|
-
|
|
79
|
-
formItemContext.
|
|
95
|
+
useProvideFormItemContext({
|
|
96
|
+
id: formItemContext.id,
|
|
97
|
+
onFieldBlur: formItemContext.onFieldBlur,
|
|
98
|
+
onFieldChange: () => {},
|
|
99
|
+
clearValidate: formItemContext.clearValidate,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// 值写入 formData 后向外广播,由 BaseFormItem 触发所属 FormItem 校验
|
|
103
|
+
const triggerFormItemChange = (value: unknown) => {
|
|
104
|
+
emit('field-value-change', value);
|
|
80
105
|
};
|
|
81
106
|
|
|
82
|
-
const attrs: any =
|
|
107
|
+
const attrs: any = useReactiveAttrs();
|
|
83
108
|
|
|
84
109
|
/**
|
|
85
110
|
* 全局默认配置注入:key = 组件名 + picker 修饰段,inject 须在 setup 同步期调用。
|
|
@@ -97,6 +122,8 @@ const componentInjectConfig = injectConfigKey
|
|
|
97
122
|
const rawInjectComponentProps = componentInjectConfig
|
|
98
123
|
? inject(componentInjectConfig.injectionKey, componentInjectConfig.default)
|
|
99
124
|
: undefined;
|
|
125
|
+
// 全量 componentVars:运行期新增的自定义组件键由此兜底读取
|
|
126
|
+
const componentVars = inject(INJECT_COMPONENT_VARS, undefined);
|
|
100
127
|
|
|
101
128
|
// setter: 向 formData 写入值,支持 valueFormatter / valueFormatter.set 转换
|
|
102
129
|
const value = computed({
|
|
@@ -123,7 +150,7 @@ const value = computed({
|
|
|
123
150
|
: undefined;
|
|
124
151
|
|
|
125
152
|
if (setFormatter) {
|
|
126
|
-
//
|
|
153
|
+
// 旧值仅在 set 转换函数声明双形参时注入
|
|
127
154
|
const oldVal =
|
|
128
155
|
setFormatter.length > 1
|
|
129
156
|
? cloneDeepIfObject(form.getFormData?.(props.path))
|
|
@@ -131,7 +158,7 @@ const value = computed({
|
|
|
131
158
|
newVal = setFormatter(val, oldVal);
|
|
132
159
|
}
|
|
133
160
|
form.setFormData?.(props.path, newVal);
|
|
134
|
-
triggerFormItemChange();
|
|
161
|
+
triggerFormItemChange(newVal);
|
|
135
162
|
// 字段配置/attrs 传入的 onUpdate:* 监听器与内部写值组合回放,参数为组件原始 emit 值
|
|
136
163
|
const { onUpdateValue } = groupedAttrs.value;
|
|
137
164
|
if (typeof onUpdateValue === 'function') {
|
|
@@ -149,7 +176,10 @@ const parentDisabled = useInjectDisabled();
|
|
|
149
176
|
* 属性分为三类:绑定属性(v-model)、组件属性(传递给组件)、插槽(动态渲染)
|
|
150
177
|
*/
|
|
151
178
|
const groupedAttrs = computed(() => {
|
|
152
|
-
const currentInjectProps =
|
|
179
|
+
const currentInjectProps = {
|
|
180
|
+
...(toValue(rawInjectComponentProps) || {}),
|
|
181
|
+
...getObject(toValue(componentVars)?.[injectConfigKey]),
|
|
182
|
+
};
|
|
153
183
|
const initProps = getInitProps(
|
|
154
184
|
{ component: props.component, picker: attrs.picker } as Field,
|
|
155
185
|
currentInjectProps,
|
|
@@ -177,10 +207,8 @@ const groupedAttrs = computed(() => {
|
|
|
177
207
|
};
|
|
178
208
|
});
|
|
179
209
|
|
|
180
|
-
// 从 ProForm 插槽注入的 slots
|
|
181
|
-
const injectedFormSlots = inject(InjectionFormSlotsKey, undefined)
|
|
182
|
-
| { value: Record<string, any> | undefined }
|
|
183
|
-
| undefined;
|
|
210
|
+
// 从 ProForm 插槽注入的 slots 集合(优先级最高)
|
|
211
|
+
const injectedFormSlots = inject(InjectionFormSlotsKey, undefined);
|
|
184
212
|
|
|
185
213
|
// 从 ProComponentProvider 注入的自定义组件映射
|
|
186
214
|
const customComponents = inject(INJECT_COMPONENTS, {});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Field } from '../../../types';
|
|
1
|
+
import type { Field } from '../../../types';
|
|
2
2
|
|
|
3
3
|
type LocaleT = (
|
|
4
4
|
key: string,
|
|
@@ -26,6 +26,17 @@ const getPlaceholderProps = (
|
|
|
26
26
|
return { placeholder: t(placeholderKey) };
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* 解析字段的 Provider 默认属性
|
|
31
|
+
*
|
|
32
|
+
* @description 仅字符串组件名取注入值(含 `date-picker` 子类型段);组件对象无注入配置,返回空对象。
|
|
33
|
+
* `date-picker` 不拼接 `picker` 段,其子类型预设由注入 key 在 BaseField 内单独解析
|
|
34
|
+
*
|
|
35
|
+
* @param field - 字段配置项
|
|
36
|
+
* @param injectProps - 该组件名对应的 Provider 注入默认值
|
|
37
|
+
* @param t - 翻译函数,用于兜底占位符文案
|
|
38
|
+
* @returns 合并占位符兜底后的初始属性
|
|
39
|
+
*/
|
|
29
40
|
export const getInitProps = (
|
|
30
41
|
field: Field,
|
|
31
42
|
injectProps: Record<string, any> = {},
|
|
@@ -43,6 +54,13 @@ export const getInitProps = (
|
|
|
43
54
|
/** 已告警过的未知组件名(模块级去重集合) */
|
|
44
55
|
const warnedUnknownComponents = new Set<string>();
|
|
45
56
|
|
|
57
|
+
/**
|
|
58
|
+
* 输出未识别组件名的告警
|
|
59
|
+
*
|
|
60
|
+
* @description 按组件名去重,同一名称仅告警一次
|
|
61
|
+
*
|
|
62
|
+
* @param name - 未识别的组件名
|
|
63
|
+
*/
|
|
46
64
|
export function warnUnknownComponent(name: string) {
|
|
47
65
|
if (warnedUnknownComponents.has(name)) return;
|
|
48
66
|
warnedUnknownComponents.add(name);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
/**
|
|
3
|
+
* 表单字段渲染引擎
|
|
4
|
+
*
|
|
3
5
|
* @component BaseFormItem
|
|
4
|
-
* @description 表单字段渲染引擎
|
|
5
6
|
*
|
|
6
7
|
* 负责将字段配置数组渲染为实际的表单项,支持:
|
|
7
8
|
* - 字段分组(嵌套 fields 递归渲染)
|
|
@@ -13,22 +14,22 @@
|
|
|
13
14
|
* ## 渲染流程
|
|
14
15
|
*
|
|
15
16
|
* 1. 遍历 fields 数组,过滤 hidden 字段
|
|
16
|
-
* 2.
|
|
17
|
+
* 2. 将字段属性分流为 GridItem / FormItem / 组件 / 插槽四类
|
|
17
18
|
* 3. 递归渲染 BaseFormItem(嵌套表单)或 BaseField(输入组件)
|
|
18
|
-
* 4.
|
|
19
|
+
* 4. 渲染后字段对象上可读取 FormItem 与组件实例
|
|
19
20
|
*
|
|
20
|
-
* @param {Fields
|
|
21
|
+
* @param {Fields} [fields] - 字段配置数组
|
|
21
22
|
* @param {boolean | GridProps} [grid] - 是否启用网格布局
|
|
22
23
|
* @param {boolean} [disabled] - 是否禁用所有子字段
|
|
23
24
|
*
|
|
24
25
|
* @internal
|
|
25
26
|
*/
|
|
26
|
-
import { getObject, toPath } from '../../../../shared/core';
|
|
27
|
+
import { getObject, isObjectItem, toPath } from '../../../../shared/core';
|
|
28
|
+
import type { GridProps } from '../../../../shared/ui';
|
|
27
29
|
import {
|
|
28
30
|
FormItem,
|
|
29
31
|
Grid as AGrid,
|
|
30
32
|
GridItem as AGridItem,
|
|
31
|
-
GridProps,
|
|
32
33
|
useProviderDisabled,
|
|
33
34
|
} from '../../../../shared/ui';
|
|
34
35
|
import { computed, inject, toRaw, toValue } from 'vue';
|
|
@@ -39,27 +40,14 @@ import ContainerFragment from '../ContainerFragment/index.vue';
|
|
|
39
40
|
import { useGroupFieldAttrs } from '../../hooks/useGroupFieldAttrs';
|
|
40
41
|
import { INJECT_CONFIG } from '../../../component-provider/constants';
|
|
41
42
|
|
|
42
|
-
/*
|
|
43
|
-
* 无 path 字段的稳定渲染 key:以字段原始对象为 key 分配自增 id,
|
|
44
|
-
* 字段插删/重排/过滤时保持 key 与对象绑定,不随数组位置漂移
|
|
45
|
-
*/
|
|
46
|
-
let fieldKeySeed = 0;
|
|
47
|
-
const fieldKeyMap = new WeakMap<object, number>();
|
|
48
|
-
const getFieldKey = (field: unknown): number => {
|
|
49
|
-
const raw = toRaw(field as object);
|
|
50
|
-
let key = fieldKeyMap.get(raw);
|
|
51
|
-
if (key === undefined) {
|
|
52
|
-
key = ++fieldKeySeed;
|
|
53
|
-
fieldKeyMap.set(raw, key);
|
|
54
|
-
}
|
|
55
|
-
return key;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
43
|
defineOptions({ name: 'BaseFormItem', inheritAttrs: false });
|
|
59
44
|
|
|
60
45
|
type Props = {
|
|
46
|
+
/** 是否启用网格布局 */
|
|
61
47
|
grid?: Grid;
|
|
48
|
+
/** 字段配置数组 */
|
|
62
49
|
fields?: Fields;
|
|
50
|
+
/** 是否禁用所有子字段 */
|
|
63
51
|
disabled?: boolean;
|
|
64
52
|
};
|
|
65
53
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -69,8 +57,10 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
69
57
|
});
|
|
70
58
|
|
|
71
59
|
const validFields = computed(() =>
|
|
72
|
-
// hidden 支持 Ref/ComputedRef
|
|
73
|
-
(props.fields ?? []).filter(
|
|
60
|
+
// hidden 支持 Ref / ComputedRef 响应式形态(统一使用 toValue 取值)
|
|
61
|
+
(props.fields ?? []).filter(
|
|
62
|
+
field => isObjectItem(field) && !toValue((field as any).hidden)
|
|
63
|
+
)
|
|
74
64
|
);
|
|
75
65
|
|
|
76
66
|
// 向下注入表单级禁用上下文,BaseField 经 useInjectDisabled 消费
|
|
@@ -93,7 +83,7 @@ const computedGridProps = computed<GridProps>(() => {
|
|
|
93
83
|
|
|
94
84
|
/**
|
|
95
85
|
* 以字段原始对象为 key 登记 FormItem / 控件实例,供 getFormItemRef / getComponentRef 读取;
|
|
96
|
-
*
|
|
86
|
+
* 字段对象被回收后对应条目不再可读。
|
|
97
87
|
*/
|
|
98
88
|
const formItemInstanceMap = new WeakMap<object, any>();
|
|
99
89
|
const componentInstanceMap = new WeakMap<object, any>();
|
|
@@ -106,7 +96,7 @@ const defineFieldAccessors = (
|
|
|
106
96
|
) => {
|
|
107
97
|
try {
|
|
108
98
|
for (const [key, getter] of Object.entries(accessors)) {
|
|
109
|
-
//
|
|
99
|
+
// 访问器仅用于字段对象读取,不参与属性遍历与字段配置透传
|
|
110
100
|
Object.defineProperty(raw, key, {
|
|
111
101
|
value: getter,
|
|
112
102
|
enumerable: false,
|
|
@@ -124,6 +114,16 @@ const defineFieldAccessors = (
|
|
|
124
114
|
}
|
|
125
115
|
};
|
|
126
116
|
|
|
117
|
+
/*
|
|
118
|
+
* 字段值变更经 BaseField 的 field-value-change 事件回传,由 FormItem 暴露的 onFieldChange 触发校验;
|
|
119
|
+
* autoLink 为 false 时保持用户自行校验的语义
|
|
120
|
+
*/
|
|
121
|
+
const onFieldValueChange = (item: any) => {
|
|
122
|
+
if (item.formItemProps?.autoLink === false) return;
|
|
123
|
+
const instance = formItemInstanceMap.get(toRaw(item.rawField));
|
|
124
|
+
instance?.onFieldChange?.();
|
|
125
|
+
};
|
|
126
|
+
|
|
127
127
|
const setFormItemRef = (field: any, el: any, formItemProps?: any) => {
|
|
128
128
|
if (!field || typeof field !== 'object') return;
|
|
129
129
|
const raw = toRaw(field);
|
|
@@ -165,10 +165,7 @@ const groupedFields = useGroupFieldAttrs(validFields);
|
|
|
165
165
|
:component="enableGrid ? AGrid : undefined"
|
|
166
166
|
v-bind="computedGridProps"
|
|
167
167
|
>
|
|
168
|
-
<template
|
|
169
|
-
v-for="item of groupedFields"
|
|
170
|
-
:key="item.path || getFieldKey(item.rawField)"
|
|
171
|
-
>
|
|
168
|
+
<template v-for="item of groupedFields" :key="item.renderKey">
|
|
172
169
|
<ContainerFragment
|
|
173
170
|
:component="enableGrid ? AGridItem : undefined"
|
|
174
171
|
v-bind="item.gridItemProps"
|
|
@@ -206,6 +203,7 @@ const groupedFields = useGroupFieldAttrs(validFields);
|
|
|
206
203
|
:ref="el => setComponentRef(item.rawField, el)"
|
|
207
204
|
v-bind="item.componentProps"
|
|
208
205
|
:path="item.path"
|
|
206
|
+
@field-value-change="onFieldValueChange(item)"
|
|
209
207
|
/>
|
|
210
208
|
</template>
|
|
211
209
|
</FormItem>
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
/**
|
|
3
|
+
* 容器分片渲染组件。用于动态渲染表单行或表单项的外部包裹容器(例如 Grid 行、Col 列等布局容器)。
|
|
4
|
+
*
|
|
3
5
|
* @component ContainerFragment
|
|
4
|
-
* @description 容器分片渲染组件。用于动态渲染表单行或表单项的外部包裹容器(例如 Grid 行、Col 列等布局容器)。
|
|
5
6
|
*
|
|
6
7
|
* @public
|
|
7
8
|
*/
|
|
8
9
|
import type { ContainerComponent } from '../../types';
|
|
9
10
|
|
|
10
11
|
type Props = {
|
|
12
|
+
/** 容器组件,未提供时不渲染包裹层 */
|
|
11
13
|
component?: ContainerComponent;
|
|
12
14
|
};
|
|
13
15
|
|