@qin-ui/element-plus-pro 1.3.3 → 1.3.5
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 +4 -4
- package/README.md +3 -2
- package/api.json +2 -2
- package/es/components/component-provider/constants/index.d.ts.map +1 -1
- package/es/components/component-provider/types/index.d.ts +3 -2
- package/es/components/component-provider/types/index.d.ts.map +1 -1
- package/es/components/form/components/BaseField/index.vue.d.ts.map +1 -1
- package/es/components/form/components/BaseFormItem/index.vue.d.ts +1 -1
- package/es/components/form/components/BaseFormItem/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.map +1 -1
- package/es/components/form/hooks/useGroupFieldAttrs.d.ts.map +1 -1
- package/es/components/form/types/index.d.ts +2 -2
- package/es/components/form/types/index.d.ts.map +1 -1
- package/es/components/table/components/ColumnControl.vue.d.ts.map +1 -1
- package/es/components/table/components/ProTable.vue.d.ts +30 -4
- package/es/components/table/components/ProTable.vue.d.ts.map +1 -1
- package/es/components/table/components/SearchForm.vue.d.ts +1 -1
- package/es/components/table/components/SearchForm.vue.d.ts.map +1 -1
- package/es/components/table/components/SizeControl.vue.d.ts +2 -2
- package/es/components/table/components/TableColumnRenderer.vue.d.ts.map +1 -1
- package/es/components/table/index.d.ts +4 -28
- package/es/components/table/index.d.ts.map +1 -1
- package/es/components/table/useTable.d.ts +1 -1
- package/es/element-plus-pro.css +12 -12
- package/es/index.js +410 -331
- package/es/index.js.map +1 -1
- package/es/shared/core/index.d.ts +1 -2
- package/es/shared/core/index.d.ts.map +1 -1
- package/es/shared/ui/index.d.ts +2 -2
- package/es/shared/ui/index.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/components/component-provider/constants/index.ts +12 -0
- package/src/components/component-provider/types/index.ts +8 -2
- package/src/components/form/components/BaseField/index.vue +25 -9
- package/src/components/form/components/BaseField/utils/index.ts +1 -1
- package/src/components/form/components/BaseFormItem/index.vue +62 -8
- package/src/components/form/components/ProForm/index.vue +24 -12
- package/src/components/form/components/SlotComponent/index.vue +4 -3
- package/src/components/form/hooks/useGroupFieldAttrs.ts +8 -15
- package/src/components/form/types/index.ts +2 -8
- package/src/components/table/components/ColumnControl.vue +40 -37
- package/src/components/table/components/ProTable.vue +74 -18
- package/src/components/table/components/SearchForm.vue +5 -4
- package/src/components/table/components/TableColumnRenderer.vue +22 -9
- package/src/components/table/index.ts +10 -30
- package/src/components/table/useTable.ts +1 -1
- package/src/shared/core/index.ts +1 -2
- package/src/shared/ui/index.ts +2 -0
- package/tsconfig.json +23 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 统一 re-export @qin-ui/pro-components-core,包内所有文件通过此文件引入 core
|
|
3
|
-
* 避免直接散列依赖 @qin-ui/pro-components-core,便于将来统一维护。
|
|
2
|
+
* 统一 re-export @qin-ui/pro-components-core,包内所有文件通过此文件引入 core 内容。
|
|
4
3
|
*/
|
|
5
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';
|
|
6
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
|
|
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,EAEV,gBAAgB,EAChB,qBAAqB,EAErB,SAAS,EACT,GAAG,EACH,GAAG,EACH,gBAAgB,EAChB,MAAM,EACN,kBAAkB,EAClB,SAAS,EACT,IAAI,EACJ,aAAa,EACb,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,6 +1,6 @@
|
|
|
1
|
-
import { ElForm as Form, ElFormItem as FormItem, ElRow as Grid, ElCol as GridItem, ElTable as Table, ElTableColumn as TableColumn, ElSpace as Space, ElDropdown as Dropdown, ElDropdownMenu as DropdownMenu, ElDropdownItem as DropdownItem, ElCheckbox as Checkbox, ElCheckboxGroup as CheckboxGroup, ElButton as Button, ElAutocomplete as AutoComplete, ElCascader as Cascader, ElDatePicker as DatePicker, ElInput as Input, ElInputNumber as InputNumber, ElSelect as Select, ElSlider as Slider, ElSwitch as Switch, ElTransfer as Transfer, ElTreeSelect as TreeSelect, ElRadioGroup as RadioGroup, ElTimePicker as TimePicker, ElTimeSelect as TimeSelect, ElPagination as Pagination, FormItemInstance, FormInstance, FormProps, FormItemProps, TableProps as _TableProps, TableColumnCtx as ColumnType, PaginationProps, RowProps as GridProps, ColProps as GridItemProps } from 'element-plus';
|
|
1
|
+
import { ElForm as Form, ElFormItem as FormItem, ElRow as Grid, ElCol as GridItem, ElTable as Table, ElTableColumn as TableColumn, ElSpace as Space, ElDropdown as Dropdown, ElDropdownMenu as DropdownMenu, ElDropdownItem as DropdownItem, ElCheckbox as Checkbox, ElCheckboxGroup as CheckboxGroup, ElButton as Button, ElAutocomplete as AutoComplete, ElCascader as Cascader, ElDatePicker as DatePicker, ElInput as Input, ElInputNumber as InputNumber, ElSelect as Select, ElSlider as Slider, ElSwitch as Switch, ElTransfer as Transfer, ElTreeSelect as TreeSelect, ElRadioGroup as RadioGroup, ElTimePicker as TimePicker, ElTimeSelect as TimeSelect, ElPagination as Pagination, FormItemInstance, FormInstance, FormProps, FormItemProps, TableProps as _TableProps, TableEmits, TableColumnCtx as ColumnType, PaginationProps, RowProps as GridProps, ColProps as GridItemProps } from 'element-plus';
|
|
2
2
|
import { MaybeRefOrGetter } from 'vue';
|
|
3
|
-
export { Form, FormItem, Grid, GridItem, Table, TableColumn, Space, Dropdown, DropdownMenu, DropdownItem, Checkbox, CheckboxGroup, Button, AutoComplete, Cascader, DatePicker, Input, InputNumber, Select, Slider, Switch, Transfer, TreeSelect, RadioGroup, TimePicker, TimeSelect, Pagination, type FormItemInstance, type FormInstance, type FormProps, type FormItemProps, type PaginationProps, type GridProps, type GridItemProps, type ColumnType, };
|
|
3
|
+
export { Form, FormItem, Grid, GridItem, Table, TableColumn, Space, Dropdown, DropdownMenu, DropdownItem, Checkbox, CheckboxGroup, Button, AutoComplete, Cascader, DatePicker, Input, InputNumber, Select, Slider, Switch, Transfer, TreeSelect, RadioGroup, TimePicker, TimeSelect, Pagination, type FormItemInstance, type FormInstance, type FormProps, type FormItemProps, type PaginationProps, type GridProps, type GridItemProps, type ColumnType, type TableEmits, };
|
|
4
4
|
export type TableProps = _TableProps<any>;
|
|
5
5
|
export declare const tableProps: () => any;
|
|
6
6
|
export declare const paginationProps: () => any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,IAAI,IAAI,EACd,UAAU,IAAI,QAAQ,EACtB,KAAK,IAAI,IAAI,EACb,KAAK,IAAI,QAAQ,EACjB,OAAO,IAAI,KAAK,EAChB,aAAa,IAAI,WAAW,EAC5B,OAAO,IAAI,KAAK,EAChB,UAAU,IAAI,QAAQ,EACtB,cAAc,IAAI,YAAY,EAC9B,cAAc,IAAI,YAAY,EAC9B,UAAU,IAAI,QAAQ,EACtB,eAAe,IAAI,aAAa,EAChC,QAAQ,IAAI,MAAM,EAClB,cAAc,IAAI,YAAY,EAC9B,UAAU,IAAI,QAAQ,EACtB,YAAY,IAAI,UAAU,EAC1B,OAAO,IAAI,KAAK,EAChB,aAAa,IAAI,WAAW,EAC5B,QAAQ,IAAI,MAAM,EAClB,QAAQ,IAAI,MAAM,EAClB,QAAQ,IAAI,MAAM,EAClB,UAAU,IAAI,QAAQ,EACtB,YAAY,IAAI,UAAU,EAC1B,YAAY,IAAI,UAAU,EAC1B,YAAY,IAAI,UAAU,EAC1B,YAAY,IAAI,UAAU,EAC1B,YAAY,IAAI,UAAU,EAE1B,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,UAAU,IAAI,WAAW,EAC9B,KAAK,cAAc,IAAI,UAAU,EACjC,KAAK,eAAe,EACpB,KAAK,QAAQ,IAAI,SAAS,EAC1B,KAAK,QAAQ,IAAI,aAAa,EAC/B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,gBAAgB,EAAsC,MAAM,KAAK,CAAC;AAEhF,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,KAAK,EACL,WAAW,EACX,MAAM,EACN,MAAM,EACN,MAAM,EACN,QAAQ,EACR,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,UAAU,GAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;AAO1C,eAAO,MAAM,UAAU,WAAoB,CAAC;AAC5C,eAAO,MAAM,eAAe,WAAyB,CAAC;AACtD,eAAO,MAAM,aAAa,WAAuB,CAAC;AAClD,eAAO,MAAM,aAAa,WAAuB,CAAC;AAIlD,eAAO,MAAM,kBAAkB,0CAS9B,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,UAAU,gBAAgB,CAAC,OAAO,GAAG,SAAS,CAAC,SAMhD,CAAC;AAEF,eAAO,MAAM,iBAAiB,0CAAqB,CAAC;AACpD,eAAO,MAAM,mBAAmB,aATpB,gBAAgB,CAAC,OAAO,GAAG,SAAS,CAAC,SASY,CAAC;AAE9D,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,IAAI,IAAI,EACd,UAAU,IAAI,QAAQ,EACtB,KAAK,IAAI,IAAI,EACb,KAAK,IAAI,QAAQ,EACjB,OAAO,IAAI,KAAK,EAChB,aAAa,IAAI,WAAW,EAC5B,OAAO,IAAI,KAAK,EAChB,UAAU,IAAI,QAAQ,EACtB,cAAc,IAAI,YAAY,EAC9B,cAAc,IAAI,YAAY,EAC9B,UAAU,IAAI,QAAQ,EACtB,eAAe,IAAI,aAAa,EAChC,QAAQ,IAAI,MAAM,EAClB,cAAc,IAAI,YAAY,EAC9B,UAAU,IAAI,QAAQ,EACtB,YAAY,IAAI,UAAU,EAC1B,OAAO,IAAI,KAAK,EAChB,aAAa,IAAI,WAAW,EAC5B,QAAQ,IAAI,MAAM,EAClB,QAAQ,IAAI,MAAM,EAClB,QAAQ,IAAI,MAAM,EAClB,UAAU,IAAI,QAAQ,EACtB,YAAY,IAAI,UAAU,EAC1B,YAAY,IAAI,UAAU,EAC1B,YAAY,IAAI,UAAU,EAC1B,YAAY,IAAI,UAAU,EAC1B,YAAY,IAAI,UAAU,EAE1B,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,UAAU,IAAI,WAAW,EAC9B,KAAK,UAAU,EACf,KAAK,cAAc,IAAI,UAAU,EACjC,KAAK,eAAe,EACpB,KAAK,QAAQ,IAAI,SAAS,EAC1B,KAAK,QAAQ,IAAI,aAAa,EAC/B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,gBAAgB,EAAsC,MAAM,KAAK,CAAC;AAEhF,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,WAAW,EACX,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,KAAK,EACL,WAAW,EACX,MAAM,EACN,MAAM,EACN,MAAM,EACN,QAAQ,EACR,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,UAAU,GAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;AAO1C,eAAO,MAAM,UAAU,WAAoB,CAAC;AAC5C,eAAO,MAAM,eAAe,WAAyB,CAAC;AACtD,eAAO,MAAM,aAAa,WAAuB,CAAC;AAClD,eAAO,MAAM,aAAa,WAAuB,CAAC;AAIlD,eAAO,MAAM,kBAAkB,0CAS9B,CAAC;AAEF,eAAO,MAAM,0BAA0B,GACrC,UAAU,gBAAgB,CAAC,OAAO,GAAG,SAAS,CAAC,SAMhD,CAAC;AAEF,eAAO,MAAM,iBAAiB,0CAAqB,CAAC;AACpD,eAAO,MAAM,mBAAmB,aATpB,gBAAgB,CAAC,OAAO,GAAG,SAAS,CAAC,SASY,CAAC;AAE9D,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qin-ui/element-plus-pro",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.5",
|
|
4
4
|
"description": "基于 element-plus 的二次封装组件",
|
|
5
5
|
"bin": {
|
|
6
6
|
"element-plus-pro": "./bin/init-ai.mjs"
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"README.md",
|
|
24
24
|
"LICENSE",
|
|
25
25
|
"api.json",
|
|
26
|
-
"AI-CONTEXT.md"
|
|
26
|
+
"AI-CONTEXT.md",
|
|
27
|
+
"tsconfig.json"
|
|
27
28
|
],
|
|
28
29
|
"homepage": "https://dufan3715.github.io/pro-components/",
|
|
29
30
|
"repository": {
|
|
@@ -39,11 +40,11 @@
|
|
|
39
40
|
},
|
|
40
41
|
"dependencies": {
|
|
41
42
|
"vue-component-type-helpers": "^3.2.5",
|
|
42
|
-
"@qin-ui/pro-components-core": "^2.0.
|
|
43
|
+
"@qin-ui/pro-components-core": "^2.0.4"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"@vue/test-utils": "^2.4.11",
|
|
46
|
-
"element-plus": "^2.
|
|
47
|
+
"element-plus": "^2.14.5",
|
|
47
48
|
"happy-dom": "^20.11.6",
|
|
48
49
|
"vitest": "^4.1.11"
|
|
49
50
|
},
|
|
@@ -122,6 +122,18 @@ export const INJECT_CONFIG: {
|
|
|
122
122
|
injectionKey: Symbol(''),
|
|
123
123
|
default: { style: { width: '100%' } },
|
|
124
124
|
},
|
|
125
|
+
'date-picker.quarter': {
|
|
126
|
+
injectionKey: Symbol(''),
|
|
127
|
+
default: { style: { width: '100%' } },
|
|
128
|
+
},
|
|
129
|
+
'date-picker.quarters': {
|
|
130
|
+
injectionKey: Symbol(''),
|
|
131
|
+
default: { style: { width: '100%' } },
|
|
132
|
+
},
|
|
133
|
+
'date-picker.quarterrange': {
|
|
134
|
+
injectionKey: Symbol(''),
|
|
135
|
+
default: { style: { width: '100%' } },
|
|
136
|
+
},
|
|
125
137
|
'date-picker.datetime': {
|
|
126
138
|
injectionKey: Symbol(''),
|
|
127
139
|
default: { style: { width: '100%' } },
|
|
@@ -7,10 +7,11 @@ import {
|
|
|
7
7
|
} from '../../../shared/ui';
|
|
8
8
|
import { ComponentName, GetComponentType } from '../../form/constants';
|
|
9
9
|
import { Base, Grid, ContainerComponent } from '../../form/types';
|
|
10
|
-
import { ProFormProps } from '../../form';
|
|
10
|
+
import { ProFormProps } from '../../form/components';
|
|
11
11
|
import type { SearchFormProps } from '../../table/components/SearchForm.vue';
|
|
12
12
|
import { AllowedComponentProps } from 'vue';
|
|
13
13
|
import type { ComponentProps } from 'vue-component-type-helpers';
|
|
14
|
+
import { ColumnControlConfig } from '../../table/types';
|
|
14
15
|
|
|
15
16
|
type PP<T extends Record<string, any>> = Partial<T & AllowedComponentProps>;
|
|
16
17
|
|
|
@@ -33,7 +34,12 @@ export type RequiredComponentVars = {
|
|
|
33
34
|
'pro-table': PP<
|
|
34
35
|
TableProps & {
|
|
35
36
|
pagination?: false | Partial<PaginationProps>;
|
|
36
|
-
control?:
|
|
37
|
+
control?:
|
|
38
|
+
| boolean
|
|
39
|
+
| {
|
|
40
|
+
sizeControl?: boolean;
|
|
41
|
+
columnControl?: boolean | ColumnControlConfig;
|
|
42
|
+
};
|
|
37
43
|
searchFormConfig?: Partial<Omit<SearchFormProps, 'form'>> & {
|
|
38
44
|
hidden?: boolean;
|
|
39
45
|
container?: ContainerComponent | false;
|
|
@@ -39,7 +39,8 @@ import {
|
|
|
39
39
|
import { cloneDeep } from '../../../../shared/core';
|
|
40
40
|
import { useDisabledContext } from '../../../../shared/ui';
|
|
41
41
|
import type { Field } from '../../types';
|
|
42
|
-
import
|
|
42
|
+
import ContainerFragment from '../ContainerFragment/index.vue';
|
|
43
|
+
import SlotComponent from '../SlotComponent/index.vue';
|
|
43
44
|
import { componentMap, InjectionFormSlotsKey } from '../../constants';
|
|
44
45
|
import {
|
|
45
46
|
INJECT_COMPONENTS,
|
|
@@ -49,6 +50,10 @@ import { useForm } from '../../hooks/useForm';
|
|
|
49
50
|
import { getInitProps, warnUnknownComponent } from './utils';
|
|
50
51
|
import { useLocale } from '../../../../locale';
|
|
51
52
|
|
|
53
|
+
const cloneDeepIfObject = (val: unknown) =>
|
|
54
|
+
// 原始值直接传递,引用值克隆快照
|
|
55
|
+
typeof val === 'object' && val !== null ? cloneDeep(val) : val;
|
|
56
|
+
|
|
52
57
|
defineOptions({ name: 'BaseField', inheritAttrs: false });
|
|
53
58
|
|
|
54
59
|
type Props = {
|
|
@@ -68,7 +73,11 @@ const componentRef = ref<any>();
|
|
|
68
73
|
|
|
69
74
|
const attrs: any = useAttrs();
|
|
70
75
|
|
|
71
|
-
|
|
76
|
+
/**
|
|
77
|
+
* 全局默认配置注入:key = 组件名 + type 修饰段,inject 须在 setup 同步期调用。
|
|
78
|
+
* 组件名与 `type` 仅取 setup 期初始值——运行期变更不会切换 Provider 的默认值预设
|
|
79
|
+
* (`date-picker.month` 等子类型预设需在初始渲染前确定)。
|
|
80
|
+
*/
|
|
72
81
|
const typeVal = attrs.type;
|
|
73
82
|
const injectConfigKey =
|
|
74
83
|
typeof props.component === 'string'
|
|
@@ -109,11 +118,18 @@ const value = computed({
|
|
|
109
118
|
// 仅当 set 转换函数需要旧值参数时,才获取旧值上下文
|
|
110
119
|
const oldVal =
|
|
111
120
|
setFormatter.length > 1
|
|
112
|
-
?
|
|
121
|
+
? cloneDeepIfObject(form.getFormData?.(props.path))
|
|
113
122
|
: undefined;
|
|
114
123
|
newVal = setFormatter(val, oldVal);
|
|
115
124
|
}
|
|
116
125
|
form.setFormData?.(props.path, newVal);
|
|
126
|
+
// 字段配置/attrs 传入的 onUpdate:* 监听器与内部写值组合回放,参数为组件原始 emit 值
|
|
127
|
+
const { onUpdateValue } = groupedAttrs.value;
|
|
128
|
+
if (typeof onUpdateValue === 'function') {
|
|
129
|
+
onUpdateValue(val);
|
|
130
|
+
} else if (Array.isArray(onUpdateValue)) {
|
|
131
|
+
onUpdateValue.forEach(listener => listener(val));
|
|
132
|
+
}
|
|
117
133
|
},
|
|
118
134
|
});
|
|
119
135
|
|
|
@@ -147,8 +163,7 @@ const groupedAttrs = computed(() => {
|
|
|
147
163
|
) as Required<Field>;
|
|
148
164
|
|
|
149
165
|
// prettier-ignore
|
|
150
|
-
|
|
151
|
-
const { valueFormatter, modelProp, slots, componentClass, componentStyle, componentContainer, [modelPropName]: _modelVal, [`onUpdate:${modelPropName}`]: _onUpdateModelVal, ...bindAttrs } = mergedProps as any;
|
|
166
|
+
const { valueFormatter, modelProp, slots, componentClass, componentStyle, componentContainer, [modelPropName]: _modelVal, [`onUpdate:${modelPropName}`]: onUpdateValue, ...bindAttrs } = mergedProps as any;
|
|
152
167
|
|
|
153
168
|
return {
|
|
154
169
|
attrs: bindAttrs,
|
|
@@ -156,12 +171,13 @@ const groupedAttrs = computed(() => {
|
|
|
156
171
|
componentContainer,
|
|
157
172
|
modelProp: modelPropName,
|
|
158
173
|
valueFormatter,
|
|
174
|
+
onUpdateValue,
|
|
159
175
|
};
|
|
160
176
|
});
|
|
161
177
|
|
|
162
|
-
// 从 ProForm 插槽注入的 slots
|
|
163
|
-
const
|
|
164
|
-
| Record<string, any>
|
|
178
|
+
// 从 ProForm 插槽注入的 slots 集合(优先级最高;shallowRef 形态,computed 内经 .value 读取建立依赖)
|
|
179
|
+
const injectedFormSlots = inject(InjectionFormSlotsKey, undefined) as
|
|
180
|
+
| { value: Record<string, any> | undefined }
|
|
165
181
|
| undefined;
|
|
166
182
|
|
|
167
183
|
// 从 ProComponentProvider 注入的自定义组件映射
|
|
@@ -172,7 +188,7 @@ const customComponents = inject(INJECT_COMPONENTS, {});
|
|
|
172
188
|
* ProForm 插槽 → 自定义组件映射 → 内置组件映射 → 原始 component 值
|
|
173
189
|
*/
|
|
174
190
|
const is = computed(() => {
|
|
175
|
-
const teleportSlot = props.path &&
|
|
191
|
+
const teleportSlot = props.path && injectedFormSlots?.value?.[props.path];
|
|
176
192
|
if (teleportSlot) return teleportSlot;
|
|
177
193
|
if (typeof props.component === 'string') {
|
|
178
194
|
const resolved =
|
|
@@ -31,10 +31,28 @@ import {
|
|
|
31
31
|
} from '../../../../shared/ui';
|
|
32
32
|
import { computed, inject, toRaw, toValue } from 'vue';
|
|
33
33
|
import type { Fields, Grid } from '../../types';
|
|
34
|
-
import
|
|
34
|
+
import BaseField from '../BaseField/index.vue';
|
|
35
|
+
import SlotComponent from '../SlotComponent/index.vue';
|
|
36
|
+
import ContainerFragment from '../ContainerFragment/index.vue';
|
|
35
37
|
import { useGroupFieldAttrs } from '../../hooks/useGroupFieldAttrs';
|
|
36
38
|
import { INJECT_CONFIG } from '../../../component-provider/constants';
|
|
37
39
|
|
|
40
|
+
/*
|
|
41
|
+
* 无 path 字段的稳定渲染 key:以字段原始对象为 key 分配自增 id,
|
|
42
|
+
* 字段插删/重排/过滤时保持 key 与对象绑定,不随数组位置漂移
|
|
43
|
+
*/
|
|
44
|
+
let fieldKeySeed = 0;
|
|
45
|
+
const fieldKeyMap = new WeakMap<object, number>();
|
|
46
|
+
const getFieldKey = (field: unknown): number => {
|
|
47
|
+
const raw = toRaw(field as object);
|
|
48
|
+
let key = fieldKeyMap.get(raw);
|
|
49
|
+
if (key === undefined) {
|
|
50
|
+
key = ++fieldKeySeed;
|
|
51
|
+
fieldKeyMap.set(raw, key);
|
|
52
|
+
}
|
|
53
|
+
return key;
|
|
54
|
+
};
|
|
55
|
+
|
|
38
56
|
defineOptions({ name: 'BaseFormItem', inheritAttrs: false });
|
|
39
57
|
|
|
40
58
|
type Props = {
|
|
@@ -73,15 +91,45 @@ const computedGridProps = computed<GridProps>(() => {
|
|
|
73
91
|
const formItemInstanceMap = new WeakMap<object, any>();
|
|
74
92
|
const componentInstanceMap = new WeakMap<object, any>();
|
|
75
93
|
|
|
94
|
+
/** 已告警过的字段对象(不可写场景去重) */
|
|
95
|
+
const warnedFrozenFields = new WeakSet<object>();
|
|
96
|
+
const defineFieldAccessors = (
|
|
97
|
+
raw: object,
|
|
98
|
+
accessors: Record<string, () => any>
|
|
99
|
+
) => {
|
|
100
|
+
try {
|
|
101
|
+
for (const [key, getter] of Object.entries(accessors)) {
|
|
102
|
+
// 不可枚举:不进入 Object.keys / spread,不随字段配置透传
|
|
103
|
+
Object.defineProperty(raw, key, {
|
|
104
|
+
value: getter,
|
|
105
|
+
enumerable: false,
|
|
106
|
+
configurable: true,
|
|
107
|
+
writable: true,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
} catch {
|
|
111
|
+
if (!warnedFrozenFields.has(raw)) {
|
|
112
|
+
warnedFrozenFields.add(raw);
|
|
113
|
+
console.warn(
|
|
114
|
+
'[pro-components] 字段配置对象不可写(如被 Object.freeze),getFormItemRef / getComponentRef 等实例访问器挂载失败。'
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
|
|
76
120
|
const setFormItemRef = (field: any, el: any, formItemProps?: any) => {
|
|
77
121
|
if (!field || typeof field !== 'object') return;
|
|
78
122
|
const raw = toRaw(field);
|
|
79
123
|
if (el) {
|
|
80
124
|
formItemInstanceMap.set(raw, el);
|
|
81
|
-
raw
|
|
82
|
-
|
|
125
|
+
defineFieldAccessors(raw, {
|
|
126
|
+
getFormItemRef: () => formItemInstanceMap.get(raw),
|
|
127
|
+
getFormItemComputedProps: () => formItemProps,
|
|
128
|
+
});
|
|
83
129
|
} else {
|
|
84
130
|
formItemInstanceMap.delete(raw);
|
|
131
|
+
delete raw.getFormItemRef;
|
|
132
|
+
delete raw.getFormItemComputedProps;
|
|
85
133
|
}
|
|
86
134
|
};
|
|
87
135
|
|
|
@@ -90,12 +138,15 @@ const setComponentRef = (field: any, el: any) => {
|
|
|
90
138
|
const raw = toRaw(field);
|
|
91
139
|
if (el) {
|
|
92
140
|
componentInstanceMap.set(raw, el);
|
|
93
|
-
raw
|
|
94
|
-
componentInstanceMap.get(raw)?.getComponentRef()
|
|
95
|
-
|
|
96
|
-
|
|
141
|
+
defineFieldAccessors(raw, {
|
|
142
|
+
getComponentRef: () => componentInstanceMap.get(raw)?.getComponentRef(),
|
|
143
|
+
getComponentComputedProps: () =>
|
|
144
|
+
componentInstanceMap.get(raw)?.getComponentComputedProps(),
|
|
145
|
+
});
|
|
97
146
|
} else {
|
|
98
147
|
componentInstanceMap.delete(raw);
|
|
148
|
+
delete raw.getComponentRef;
|
|
149
|
+
delete raw.getComponentComputedProps;
|
|
99
150
|
}
|
|
100
151
|
};
|
|
101
152
|
|
|
@@ -108,7 +159,10 @@ const groupedFields = useGroupFieldAttrs(validFields);
|
|
|
108
159
|
v-bind="computedGridProps"
|
|
109
160
|
style="width: 100%"
|
|
110
161
|
>
|
|
111
|
-
<template
|
|
162
|
+
<template
|
|
163
|
+
v-for="item of groupedFields"
|
|
164
|
+
:key="item.path || getFieldKey(item.rawField)"
|
|
165
|
+
>
|
|
112
166
|
<ContainerFragment
|
|
113
167
|
:component="enableGrid ? ElGridItem : undefined"
|
|
114
168
|
v-bind="item.gridItemProps"
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
*
|
|
10
10
|
* 1. 数据隔离:ProForm 本身不负责存储和管理表单状态,所有核心状态(formData, fields, 校验规则)
|
|
11
11
|
* 均交由底层的 `useForm`(@qin-ui/pro-components-core)驱动。
|
|
12
|
-
* 2. 上下文透传:通过 `provide`
|
|
13
|
-
* 3. 递归渲染:网格布局和具体字段的解析交由 `<BaseFormItem>`
|
|
12
|
+
* 2. 上下文透传:通过 `provide` 将核心状态下发给子组件。
|
|
13
|
+
* 3. 递归渲染:网格布局和具体字段的解析交由 `<BaseFormItem>` 递归完成。
|
|
14
14
|
*
|
|
15
15
|
* 通过配置驱动的方式快速构建表单,支持:
|
|
16
16
|
* - 字段联动、嵌套字段、自定义组件、网格布局
|
|
@@ -29,16 +29,19 @@ import {
|
|
|
29
29
|
FormProps as ElFormProps,
|
|
30
30
|
} from '../../../../shared/ui';
|
|
31
31
|
import {
|
|
32
|
+
computed,
|
|
32
33
|
inject,
|
|
33
34
|
mergeProps,
|
|
35
|
+
onUpdated,
|
|
34
36
|
provide,
|
|
37
|
+
shallowRef,
|
|
35
38
|
toValue,
|
|
36
|
-
|
|
37
|
-
computed,
|
|
39
|
+
triggerRef,
|
|
38
40
|
useAttrs,
|
|
41
|
+
type Slot,
|
|
39
42
|
} from 'vue';
|
|
40
43
|
import { INJECT_CONFIG } from '../../../component-provider/constants';
|
|
41
|
-
import
|
|
44
|
+
import BaseFormItem from '../BaseFormItem/index.vue';
|
|
42
45
|
import { InjectionFormKey, InjectionFormSlotsKey } from '../../constants';
|
|
43
46
|
import type { Grid, VModelProps, PathProps } from '../../types';
|
|
44
47
|
import {
|
|
@@ -63,12 +66,12 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
63
66
|
|
|
64
67
|
/**
|
|
65
68
|
* 依赖注入中心:
|
|
66
|
-
*
|
|
69
|
+
* 未传 form 实例(含运行期置空)时惰性初始化内部表单实例;
|
|
67
70
|
* 将 Form 实例注入到 Vue Context 中,供深层子组件跨层级直接访问数据和方法。
|
|
68
71
|
*/
|
|
69
|
-
|
|
72
|
+
let fallbackForm: F | undefined;
|
|
70
73
|
const currentForm = computed(
|
|
71
|
-
() => props.form ?? (fallbackForm as unknown as F)
|
|
74
|
+
() => props.form ?? (fallbackForm ??= useForm() as unknown as F)
|
|
72
75
|
);
|
|
73
76
|
|
|
74
77
|
/**
|
|
@@ -86,9 +89,14 @@ const fields = computed(() => {
|
|
|
86
89
|
const formData = computed(() => currentForm.value?.formData);
|
|
87
90
|
const setFormRef = (el: any) => currentForm.value?.setFormRef?.(el);
|
|
88
91
|
|
|
92
|
+
/*
|
|
93
|
+
* formKey 子树重挂载契约:以 WeakMap 为每个 form 实例生成自增 key,绑定到原生 Form 的 :key
|
|
94
|
+
* :form 运行期替换为全新实例时强制整棵表单子树重新挂载,重置宿主校验状态与深层字段非受控状态
|
|
95
|
+
*/
|
|
89
96
|
let formInstanceCounter = 0;
|
|
90
97
|
const formInstanceKeyMap = new WeakMap<object, number>();
|
|
91
98
|
const getFormKey = (f: object) => {
|
|
99
|
+
if (f == null) return 0;
|
|
92
100
|
if (!formInstanceKeyMap.has(f)) {
|
|
93
101
|
formInstanceKeyMap.set(f, ++formInstanceCounter);
|
|
94
102
|
}
|
|
@@ -105,7 +113,6 @@ const attrs = useAttrs();
|
|
|
105
113
|
*/
|
|
106
114
|
const injectAttrs = computed(() => {
|
|
107
115
|
const raw = toValue(injectFormConfig);
|
|
108
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
109
116
|
const { grid: _injectGrid, ...rest } = raw || {};
|
|
110
117
|
return rest;
|
|
111
118
|
});
|
|
@@ -121,14 +128,19 @@ type FieldSlots = Record<ExtractPath<F>, Slot<FieldSlotProps>>;
|
|
|
121
128
|
|
|
122
129
|
const slots = defineSlots<Partial<FieldSlots & { default: Slot }>>();
|
|
123
130
|
|
|
124
|
-
|
|
131
|
+
/*
|
|
125
132
|
* 动态插槽映射中心 (Slot Teleporting):
|
|
126
|
-
*
|
|
133
|
+
* slots 以 shallowRef 注入,组件每次更新后触发通知,深层 BaseField 可感知父级运行期增删的具名插槽
|
|
127
134
|
*/
|
|
128
|
-
|
|
135
|
+
const formSlotsRef = shallowRef<Record<string, any>>(slots);
|
|
136
|
+
onUpdated(() => {
|
|
137
|
+
triggerRef(formSlotsRef);
|
|
138
|
+
});
|
|
139
|
+
provide(InjectionFormSlotsKey, formSlotsRef);
|
|
129
140
|
</script>
|
|
130
141
|
|
|
131
142
|
<template>
|
|
143
|
+
<!-- el-form 渲染原生 form 元素,拦截回车触发的默认提交 -->
|
|
132
144
|
<ElForm
|
|
133
145
|
:key="formKey"
|
|
134
146
|
:ref="setFormRef"
|
|
@@ -14,9 +14,10 @@ type Props = {
|
|
|
14
14
|
};
|
|
15
15
|
defineProps<Props>();
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
/*
|
|
18
|
+
* 可组件化渲染判定:VNode / 函数(含函数式组件)/ 组件定义对象
|
|
19
|
+
* 其余(string/number/boolean/null/undefined)一律按文本渲染,不作为 <component :is> 的标签名解析
|
|
20
|
+
*/
|
|
20
21
|
const isRenderable = (c: Props['component']) =>
|
|
21
22
|
c !== null &&
|
|
22
23
|
c !== undefined &&
|
|
@@ -17,6 +17,7 @@ const gridItemPropKeys = Object.keys(gridItemProps());
|
|
|
17
17
|
// 模块级 Set:字段循环内 O(1) 命中,替代数组 includes 线性扫描
|
|
18
18
|
const gridItemPropKeySet = new Set<string>(gridItemPropKeys);
|
|
19
19
|
const formItemPropKeySet = new Set<string>(formItemPropKeys);
|
|
20
|
+
const formItemSlotKeySet = new Set<string>(FORM_ITEM_SLOT_KEYS);
|
|
20
21
|
|
|
21
22
|
export interface GroupedField {
|
|
22
23
|
path: string;
|
|
@@ -45,22 +46,11 @@ export function useGroupFieldAttrs(validFields: ComputedRef<Field[]>) {
|
|
|
45
46
|
|
|
46
47
|
if (isPlainObject(field)) {
|
|
47
48
|
// prettier-ignore
|
|
48
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
49
49
|
const { path, name, fields, formItemClass, formItemStyle, formItemContainer, hidden, span, getFormItemRef, getComponentRef, getFormItemComputedProps, getComponentComputedProps, slots = {}, formItemDataAttrs = {}, componentDataAttrs = {}, extraProps, ...rest } =
|
|
50
50
|
field as any;
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
style: injectStyle,
|
|
55
|
-
span: injectSpan,
|
|
56
|
-
formItemContainer: injectFormItemContainer,
|
|
57
|
-
xs,
|
|
58
|
-
sm,
|
|
59
|
-
md,
|
|
60
|
-
lg,
|
|
61
|
-
xl,
|
|
62
|
-
...injectRest
|
|
63
|
-
} = rawInjectProps;
|
|
52
|
+
// prettier-ignore
|
|
53
|
+
const { class: injectClassName, style: injectStyle, span: injectSpan, formItemContainer: injectFormItemContainer, xs, sm, md, lg, xl, ...injectRest } = rawInjectProps;
|
|
64
54
|
|
|
65
55
|
// 字段显式 span 优先,否则回退注入配置的响应式断点
|
|
66
56
|
const initGridItemProps =
|
|
@@ -68,7 +58,10 @@ export function useGroupFieldAttrs(validFields: ComputedRef<Field[]>) {
|
|
|
68
58
|
? { span }
|
|
69
59
|
: { xs, sm, md, lg, xl, span: injectSpan };
|
|
70
60
|
|
|
71
|
-
|
|
61
|
+
// 分组字段默认整行(span 兜底 24),注入断点同样生效
|
|
62
|
+
gridItemProps = fields
|
|
63
|
+
? { ...initGridItemProps, span: span ?? 24 }
|
|
64
|
+
: initGridItemProps;
|
|
72
65
|
formItemProps = mergeProps(
|
|
73
66
|
injectRest as any,
|
|
74
67
|
{ class: injectClassName, style: injectStyle },
|
|
@@ -89,7 +82,7 @@ export function useGroupFieldAttrs(validFields: ComputedRef<Field[]>) {
|
|
|
89
82
|
|
|
90
83
|
Object.assign(componentProps, componentDataAttrs);
|
|
91
84
|
Object.keys(slots).forEach(k => {
|
|
92
|
-
if (
|
|
85
|
+
if (formItemSlotKeySet.has(k)) {
|
|
93
86
|
formItemSlots[k] = slots[k];
|
|
94
87
|
} else {
|
|
95
88
|
componentProps.slots[k] = slots[k];
|
|
@@ -290,10 +290,7 @@ type WithFields<D extends Data = Data> = WithRef<
|
|
|
290
290
|
/**
|
|
291
291
|
* @description 合并 FormItem 插槽与组件插槽
|
|
292
292
|
*/
|
|
293
|
-
export type MergeSlots<
|
|
294
|
-
T extends abstract new (...args: any) => any,
|
|
295
|
-
CS = ComponentSlots<T>,
|
|
296
|
-
> = Partial<{
|
|
293
|
+
export type MergeSlots<T, CS = ComponentSlots<T>> = Partial<{
|
|
297
294
|
[K in keyof FormItemSlots | keyof CS]: K extends keyof FormItemSlots
|
|
298
295
|
? FormItemSlots[K]
|
|
299
296
|
: K extends keyof CS
|
|
@@ -306,10 +303,7 @@ export type MergeSlots<
|
|
|
306
303
|
* @template T - Vue 组件类型
|
|
307
304
|
* @template D - 数据对象类型
|
|
308
305
|
*/
|
|
309
|
-
type WithComponent<
|
|
310
|
-
T extends abstract new (...args: any) => any,
|
|
311
|
-
D extends Data = Data,
|
|
312
|
-
> = Omit<
|
|
306
|
+
type WithComponent<T, D extends Data = Data> = Omit<
|
|
313
307
|
WithCommon<Partial<ComponentProps<T>>, D>,
|
|
314
308
|
keyof VNodeProps | 'slots'
|
|
315
309
|
> & {
|
|
@@ -28,9 +28,10 @@ const { t } = useLocale();
|
|
|
28
28
|
const checkAll = ref(false);
|
|
29
29
|
const indeterminate = ref(false);
|
|
30
30
|
|
|
31
|
-
const getColumnKey = (column: Column
|
|
31
|
+
const getColumnKey = (column: Column) => {
|
|
32
32
|
const rawKey = column.key ?? column.prop;
|
|
33
|
-
if (rawKey === undefined || rawKey === null
|
|
33
|
+
if (rawKey === undefined || rawKey === null || rawKey === '')
|
|
34
|
+
return undefined;
|
|
34
35
|
return normalizePathKey(rawKey);
|
|
35
36
|
};
|
|
36
37
|
|
|
@@ -43,39 +44,39 @@ const checkedColumnsOptions = computed<
|
|
|
43
44
|
column: Column;
|
|
44
45
|
}>
|
|
45
46
|
>(() =>
|
|
46
|
-
props.columns
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
47
|
+
props.columns.flatMap(item => {
|
|
48
|
+
const key = getColumnKey(item);
|
|
49
|
+
// 无 key/prop 列不进入列控面板
|
|
50
|
+
if (key === undefined) return [];
|
|
51
|
+
// 默认排除内部序号列 __INDEX__ 及显式指定的 excludedKeys
|
|
52
|
+
if (
|
|
53
|
+
key === '__INDEX__' ||
|
|
54
|
+
(item as any).type === 'index' ||
|
|
55
|
+
props.columnControl?.excludedKeys?.some(ek => String(ek) === key)
|
|
56
|
+
)
|
|
57
|
+
return [];
|
|
58
|
+
const disabled =
|
|
59
|
+
props.columnControl?.disabledKeys?.some(dk => String(dk) === key) ??
|
|
60
|
+
false;
|
|
61
|
+
const rawTitle = item.label ?? (item as any).title;
|
|
62
|
+
const titleLabel = typeof rawTitle === 'string' ? rawTitle : undefined;
|
|
63
|
+
const propLabel =
|
|
64
|
+
item.prop !== undefined && item.prop !== null
|
|
65
|
+
? String(item.prop)
|
|
66
|
+
: undefined;
|
|
67
|
+
const label =
|
|
68
|
+
(props.columnControl?.labels?.[key] as string) ??
|
|
69
|
+
titleLabel ??
|
|
70
|
+
propLabel ??
|
|
71
|
+
key;
|
|
72
|
+
return {
|
|
73
|
+
label,
|
|
74
|
+
value: key,
|
|
75
|
+
checked: !item.hidden || !!disabled,
|
|
76
|
+
disabled: !!disabled,
|
|
77
|
+
column: item,
|
|
78
|
+
};
|
|
79
|
+
})
|
|
79
80
|
);
|
|
80
81
|
|
|
81
82
|
/** 可被用户勾选/取消的列(非 disabled) */
|
|
@@ -90,10 +91,12 @@ const checkedColumnKeys = computed({
|
|
|
90
91
|
);
|
|
91
92
|
},
|
|
92
93
|
set(val: string[]) {
|
|
94
|
+
// 仅写 hidden 发生翻转的列
|
|
95
|
+
const checkedSet = new Set(val);
|
|
93
96
|
checkedColumnsOptions.value.forEach(item => {
|
|
94
|
-
if (item.disabled) return;
|
|
97
|
+
if (item.disabled || item.checked === checkedSet.has(item.value)) return;
|
|
95
98
|
props.table?.setColumn(item.value as any, {
|
|
96
|
-
hidden: !
|
|
99
|
+
hidden: !checkedSet.has(item.value),
|
|
97
100
|
});
|
|
98
101
|
});
|
|
99
102
|
},
|