@qin-ui/element-plus-pro 1.3.5 → 1.4.1
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 +27 -3
- package/README.md +42 -31
- package/api.json +69 -38
- package/es/components/component-provider/components/index.vue.d.ts +10 -3
- package/es/components/component-provider/components/index.vue.d.ts.map +1 -1
- package/es/components/component-provider/constants/index.d.ts +22 -4
- package/es/components/component-provider/constants/index.d.ts.map +1 -1
- package/es/components/component-provider/types/index.d.ts +15 -1
- 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/BaseField/utils/index.d.ts +15 -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 -1
- package/es/components/form/components/BaseFormItem/index.vue.d.ts.map +1 -1
- 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.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 +8 -2
- package/es/components/form/constants/index.d.ts.map +1 -1
- package/es/components/form/hooks/useFields.d.ts.map +1 -1
- package/es/components/form/hooks/useForm.d.ts.map +1 -1
- package/es/components/form/hooks/useGroupFieldAttrs.d.ts +9 -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 +65 -50
- 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 +1 -1
- package/es/components/table/components/ColumnControl.vue.d.ts.map +1 -1
- package/es/components/table/components/ProTable.vue.d.ts +15 -1
- package/es/components/table/components/ProTable.vue.d.ts.map +1 -1
- package/es/components/table/components/SearchForm.vue.d.ts +13 -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/components/TableColumnRenderer.vue.d.ts +14 -14
- package/es/components/table/components/TableColumnRenderer.vue.d.ts.map +1 -1
- package/es/components/table/hooks/index.d.ts +2 -0
- package/es/components/table/hooks/index.d.ts.map +1 -0
- package/es/components/table/{useTable.d.ts → hooks/useTable.d.ts} +3 -3
- package/es/components/table/hooks/useTable.d.ts.map +1 -0
- package/es/components/table/index.d.ts +6 -2
- package/es/components/table/index.d.ts.map +1 -1
- package/es/components/table/types/index.d.ts +16 -12
- package/es/components/table/types/index.d.ts.map +1 -1
- package/es/element-plus-pro.css +14 -14
- package/es/index.d.ts +9 -6
- package/es/index.d.ts.map +1 -1
- package/es/index.js +307 -227
- package/es/index.js.map +1 -1
- package/es/locale/index.d.ts +2 -1
- 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 +20 -2
- package/es/shared/ui/index.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/components/component-provider/components/index.vue +48 -21
- package/src/components/component-provider/constants/index.ts +34 -6
- package/src/components/component-provider/types/index.ts +21 -7
- package/src/components/form/components/BaseField/index.vue +25 -12
- package/src/components/form/components/BaseField/utils/index.ts +16 -1
- package/src/components/form/components/BaseFormItem/index.vue +25 -32
- package/src/components/form/components/ContainerFragment/index.vue +3 -1
- package/src/components/form/components/ProForm/index.vue +41 -21
- package/src/components/form/components/SlotComponent/index.vue +4 -2
- package/src/components/form/components/index.ts +8 -1
- package/src/components/form/constants/index.ts +9 -2
- package/src/components/form/hooks/useFields.ts +5 -2
- package/src/components/form/hooks/useForm.ts +8 -1
- package/src/components/form/hooks/useGroupFieldAttrs.ts +24 -17
- package/src/components/form/index.ts +1 -3
- package/src/components/form/types/index.ts +71 -52
- package/src/components/form/utils/fieldKey.ts +27 -0
- package/src/components/table/components/ColumnControl.vue +16 -6
- package/src/components/table/components/ProTable.vue +183 -93
- package/src/components/table/components/SearchForm.vue +60 -22
- package/src/components/table/components/SizeControl.vue +23 -1
- package/src/components/table/components/TableColumnRenderer.vue +82 -63
- package/src/components/table/hooks/index.ts +1 -0
- package/src/components/table/{useTable.ts → hooks/useTable.ts} +6 -4
- package/src/components/table/index.ts +11 -2
- package/src/components/table/types/index.ts +17 -13
- package/src/index.ts +13 -7
- package/src/locale/index.ts +4 -2
- package/src/shared/core/index.ts +11 -0
- package/src/shared/ui/index.ts +29 -5
- package/tsconfig.json +0 -1
- package/es/components/table/useTable.d.ts.map +0 -1
|
@@ -4,27 +4,31 @@ import type {
|
|
|
4
4
|
GridItemProps,
|
|
5
5
|
FormInstance,
|
|
6
6
|
} from '../../../shared/ui';
|
|
7
|
-
import { FormItem } from '../../../shared/ui';
|
|
7
|
+
import type { FormItem } from '../../../shared/ui';
|
|
8
8
|
import type {
|
|
9
9
|
ComponentProps,
|
|
10
10
|
ComponentSlots,
|
|
11
11
|
} from 'vue-component-type-helpers';
|
|
12
|
+
import type { VNode, VNodeProps } from 'vue';
|
|
12
13
|
import {
|
|
13
|
-
type
|
|
14
|
+
type ClassValue,
|
|
14
15
|
type Component,
|
|
15
16
|
type Raw,
|
|
16
17
|
type MaybeRef,
|
|
17
18
|
type ComputedRef,
|
|
18
|
-
|
|
19
|
-
VNodeProps,
|
|
19
|
+
type StyleValue,
|
|
20
20
|
} from 'vue';
|
|
21
21
|
import type { Data, Path } from '../../../shared/core';
|
|
22
|
-
import { ComponentName, GetComponentType } from '../constants';
|
|
22
|
+
import type { ComponentName, GetComponentType } from '../constants';
|
|
23
|
+
import type { AdditionalMethods } from '../../../shared/core';
|
|
24
|
+
import type { FormItemInstance } from '../../../shared/ui';
|
|
23
25
|
|
|
24
26
|
export type { FormInstance };
|
|
25
27
|
|
|
28
|
+
/** 路径属性:把字段路径随 props 下发给渲染组件 */
|
|
26
29
|
export type PathProps = { path?: string } & Data;
|
|
27
30
|
|
|
31
|
+
/** v-model 绑定属性:模型值与更新回调 */
|
|
28
32
|
export type VModelProps<T = any> = {
|
|
29
33
|
modelValue?: T;
|
|
30
34
|
'onUpdate:modelValue'?: (val: T) => void;
|
|
@@ -59,13 +63,13 @@ export type ValueFormatter =
|
|
|
59
63
|
| { get?: (val: any) => any; set?: (val: any, oldVal?: any) => any };
|
|
60
64
|
|
|
61
65
|
/**
|
|
62
|
-
*
|
|
66
|
+
* 自定义渲染组件类型
|
|
63
67
|
* @example (p, ctx) => h('div', ctx.attrs)
|
|
64
68
|
*/
|
|
65
69
|
export type RenderComponentType = Component<VModelProps & PathProps>;
|
|
66
70
|
|
|
67
71
|
/**
|
|
68
|
-
*
|
|
72
|
+
* 插槽组件类型:VNode、组件定义、渲染函数或文本
|
|
69
73
|
*/
|
|
70
74
|
export type SlotComponentType =
|
|
71
75
|
| Component<PathProps>
|
|
@@ -78,45 +82,49 @@ export type SlotComponentType =
|
|
|
78
82
|
| ((...args: any[]) => SlotComponentType);
|
|
79
83
|
|
|
80
84
|
/**
|
|
81
|
-
*
|
|
85
|
+
* 容器组件类型
|
|
82
86
|
*/
|
|
83
87
|
export type ContainerComponent = Component<PathProps>;
|
|
84
88
|
|
|
85
89
|
/**
|
|
86
|
-
*
|
|
90
|
+
* 插槽对象类型,键为插槽名
|
|
87
91
|
*/
|
|
88
92
|
export type Slots = {
|
|
89
93
|
[name: string]: SlotComponentType;
|
|
90
94
|
};
|
|
91
95
|
|
|
96
|
+
/** 选项数据:label 展示、value 取值,可携带任意扩展字段 */
|
|
92
97
|
export type Option = { label: string; value: any; [x: string]: any };
|
|
98
|
+
/** 选项数据数组 */
|
|
93
99
|
export type Options = Array<Option>;
|
|
94
100
|
|
|
101
|
+
/** 网格布局配置:布尔即启用默认布局,传对象作为 GridProps */
|
|
95
102
|
export type Grid = boolean | (GridProps & {});
|
|
96
103
|
|
|
104
|
+
/** FormItem 插槽集合(label / error 等) */
|
|
97
105
|
export type FormItemSlots = ComponentSlots<typeof FormItem>;
|
|
98
106
|
|
|
99
107
|
type BaseCommon<D extends Data = Data> = {
|
|
100
108
|
/**
|
|
101
|
-
*
|
|
109
|
+
* 字段标识(namePath),与 prop 同时配置时以 prop 为准;`name` 作为控件自身属性向下透传
|
|
110
|
+
*
|
|
111
|
+
* 嵌套字段的 `path` 使用各自独立的完整路径(不与父级路径拼接),重复路径需自行保证唯一。
|
|
102
112
|
* @example 'name' | 'age' | 'sex' | ...
|
|
103
113
|
*/
|
|
104
114
|
path?: Path<D>;
|
|
105
|
-
/**
|
|
106
|
-
* @description 字段是否隐藏
|
|
107
|
-
*/
|
|
115
|
+
/** 字段是否隐藏;支持布尔、Ref 与 ComputedRef 形式,渲染期统一按 `toValue` 取值 */
|
|
108
116
|
hidden?: boolean;
|
|
109
117
|
/**
|
|
110
|
-
*
|
|
118
|
+
* 字段是否禁用;字段级取值优先,未显式指定时继承上层(表单或宿主 Provider)的禁用上下文
|
|
111
119
|
*/
|
|
112
120
|
disabled?: boolean;
|
|
113
121
|
/**
|
|
114
|
-
*
|
|
122
|
+
* 字段中文名称,支持字符串或组件
|
|
115
123
|
* @example '姓名' | '年龄' | '性别' | () => h('span', '自定义标签')
|
|
116
124
|
*/
|
|
117
125
|
label?: SlotComponentType;
|
|
118
126
|
/**
|
|
119
|
-
*
|
|
127
|
+
* 字段插槽配置,可包含 FormItem 插槽与组件插槽
|
|
120
128
|
* @example
|
|
121
129
|
* ```js
|
|
122
130
|
* slots: {
|
|
@@ -128,27 +136,27 @@ type BaseCommon<D extends Data = Data> = {
|
|
|
128
136
|
*/
|
|
129
137
|
slots?: Partial<FormItemSlots>;
|
|
130
138
|
/**
|
|
131
|
-
*
|
|
139
|
+
* FormItem 样式
|
|
132
140
|
* @example { marginBottom: '8px', padding: '12px' }
|
|
133
141
|
*/
|
|
134
|
-
formItemStyle?:
|
|
142
|
+
formItemStyle?: StyleValue;
|
|
135
143
|
/**
|
|
136
|
-
*
|
|
144
|
+
* FormItem 类名
|
|
137
145
|
* @example 'custom-form-item' | 'required-field'
|
|
138
146
|
*/
|
|
139
|
-
formItemClass?:
|
|
147
|
+
formItemClass?: ClassValue;
|
|
140
148
|
/**
|
|
141
|
-
*
|
|
149
|
+
* FormItem 外层包裹组件
|
|
142
150
|
* @example (props, ctx) => h('div', { class: 'custom-container' }, ctx.slots.default?.())
|
|
143
151
|
*/
|
|
144
152
|
formItemContainer?: ContainerComponent;
|
|
145
153
|
/**
|
|
146
|
-
*
|
|
154
|
+
* 附加到 FormItem DOM 节点上的属性
|
|
147
155
|
* @example { 'data-form-item-test': 'test-value', 'aria-label': 'name' }
|
|
148
156
|
*/
|
|
149
157
|
formItemDataAttrs?: Record<string, string>;
|
|
150
158
|
/**
|
|
151
|
-
*
|
|
159
|
+
* 业务侧自定义标识属性,不作为组件属性透传
|
|
152
160
|
* @example { group: 'group-1' }
|
|
153
161
|
*/
|
|
154
162
|
extraProps?: Record<string, any>;
|
|
@@ -156,43 +164,45 @@ type BaseCommon<D extends Data = Data> = {
|
|
|
156
164
|
|
|
157
165
|
type BaseWithFields<D extends Data = Data> = BaseCommon<D> & {
|
|
158
166
|
/**
|
|
159
|
-
*
|
|
160
|
-
* @example [{
|
|
167
|
+
* 嵌套子字段配置
|
|
168
|
+
* @example [{ path: 'firstName', label: '名' }, { path: 'lastName', label: '姓' }]
|
|
161
169
|
*/
|
|
162
170
|
fields: Fields<D>;
|
|
163
171
|
/**
|
|
164
|
-
*
|
|
172
|
+
* 网格布局配置,true 表示使用默认网格布局
|
|
165
173
|
* @example boolean | { gutter: 24 }
|
|
166
174
|
*/
|
|
167
175
|
grid?: Grid;
|
|
168
176
|
component?: never;
|
|
169
177
|
/**
|
|
170
|
-
*
|
|
178
|
+
* 组件样式(仅非嵌套字段有效)
|
|
171
179
|
* @example { width: '100%', borderColor: '#d9d9d9' }
|
|
172
180
|
*/
|
|
173
181
|
componentStyle?: never;
|
|
174
182
|
/**
|
|
175
|
-
*
|
|
183
|
+
* 组件类名(仅非嵌套字段有效)
|
|
176
184
|
* @example 'custom-input' | 'error-input'
|
|
177
185
|
*/
|
|
178
186
|
componentClass?: never;
|
|
179
187
|
/**
|
|
180
|
-
*
|
|
188
|
+
* 组件外层包裹组件(仅非嵌套字段有效)
|
|
181
189
|
* @example (props, ctx) => h('div', { class: 'input-wrapper' }, ctx.slots.default?.())
|
|
182
190
|
*/
|
|
183
191
|
componentContainer?: never;
|
|
184
192
|
/**
|
|
185
|
-
*
|
|
193
|
+
* 附加到组件 DOM 节点上的属性(仅非嵌套字段有效)
|
|
186
194
|
* @example { 'data-test': 'input-value', 'aria-label': 'name' }
|
|
187
195
|
*/
|
|
188
196
|
componentDataAttrs?: never;
|
|
189
197
|
/**
|
|
190
|
-
*
|
|
198
|
+
* 字段值处理函数,在 onUpdateValue 前执行(仅非嵌套字段有效)
|
|
199
|
+
*
|
|
200
|
+
* 函数返回值作为更新值;也可传 `{ get, set }` 对象分别处理读取与写入
|
|
191
201
|
* @example (val) => val?.trim()
|
|
192
202
|
*/
|
|
193
203
|
valueFormatter?: never;
|
|
194
204
|
/**
|
|
195
|
-
*
|
|
205
|
+
* v-model 绑定的属性名,默认 `modelValue`(仅非嵌套字段有效)
|
|
196
206
|
*/
|
|
197
207
|
modelProp?: never;
|
|
198
208
|
};
|
|
@@ -201,45 +211,47 @@ type BaseWithoutFields<D extends Data = Data> = BaseCommon<D> & {
|
|
|
201
211
|
fields?: undefined;
|
|
202
212
|
grid?: never;
|
|
203
213
|
/**
|
|
204
|
-
*
|
|
214
|
+
* 组件样式(仅非嵌套字段有效)
|
|
205
215
|
* @example { width: '100%', borderColor: '#d9d9d9' }
|
|
206
216
|
*/
|
|
207
|
-
componentStyle?:
|
|
217
|
+
componentStyle?: StyleValue;
|
|
208
218
|
/**
|
|
209
|
-
*
|
|
219
|
+
* 组件类名(仅非嵌套字段有效)
|
|
210
220
|
* @example 'custom-input' | 'error-input'
|
|
211
221
|
*/
|
|
212
|
-
componentClass?:
|
|
222
|
+
componentClass?: ClassValue;
|
|
213
223
|
/**
|
|
214
|
-
*
|
|
224
|
+
* 组件外层包裹组件(仅非嵌套字段有效)
|
|
215
225
|
* @example (props, ctx) => h('div', { class: 'input-wrapper' }, ctx.slots.default?.())
|
|
216
226
|
*/
|
|
217
227
|
componentContainer?: ContainerComponent;
|
|
218
228
|
/**
|
|
219
|
-
*
|
|
229
|
+
* 附加到组件 DOM 节点上的属性(仅非嵌套字段有效)
|
|
220
230
|
* @example { 'data-test': 'input-value', 'aria-label': 'name' }
|
|
221
231
|
*/
|
|
222
232
|
componentDataAttrs?: Record<string, string>;
|
|
223
233
|
/**
|
|
224
|
-
*
|
|
234
|
+
* 字段值处理函数,在 onUpdateValue 前执行
|
|
235
|
+
*
|
|
236
|
+
* 函数返回值作为更新值;也可传 `{ get, set }` 对象分别处理读取与写入
|
|
225
237
|
* @example (val) => val?.trim()
|
|
226
238
|
*/
|
|
227
239
|
valueFormatter?: ValueFormatter;
|
|
228
240
|
/**
|
|
229
|
-
*
|
|
241
|
+
* v-model 绑定的属性名,默认 `modelValue`
|
|
230
242
|
*/
|
|
231
243
|
modelProp?: string;
|
|
232
244
|
};
|
|
233
245
|
|
|
234
246
|
/**
|
|
235
|
-
*
|
|
247
|
+
* 基础公共字段类型(非嵌套字段与嵌套字段两个分支)
|
|
236
248
|
*/
|
|
237
249
|
export type Base<D extends Data = Data> =
|
|
238
250
|
| BaseWithFields<D>
|
|
239
251
|
| BaseWithoutFields<D>;
|
|
240
252
|
|
|
241
253
|
/**
|
|
242
|
-
*
|
|
254
|
+
* 内置组件名到字段配置类型的映射
|
|
243
255
|
*/
|
|
244
256
|
export type FieldTypeMap<D extends Data = Data> = {
|
|
245
257
|
[K in ComponentName]: K extends 'custom'
|
|
@@ -250,7 +262,7 @@ export type FieldTypeMap<D extends Data = Data> = {
|
|
|
250
262
|
};
|
|
251
263
|
|
|
252
264
|
/**
|
|
253
|
-
*
|
|
265
|
+
* 不支持响应式取值的字段属性名
|
|
254
266
|
*/
|
|
255
267
|
type NotSupportedRefOrGetterProps =
|
|
256
268
|
| 'component'
|
|
@@ -264,7 +276,8 @@ type NotSupportedRefOrGetterProps =
|
|
|
264
276
|
type MaybeRefOrComputedRef<T = any> = MaybeRef<T> | ComputedRef<T>;
|
|
265
277
|
|
|
266
278
|
/**
|
|
267
|
-
*
|
|
279
|
+
* 为对象属性添加响应式支持的类型
|
|
280
|
+
*
|
|
268
281
|
* @template T - 原始类型
|
|
269
282
|
*/
|
|
270
283
|
export type WithRef<T> = {
|
|
@@ -288,7 +301,7 @@ type WithFields<D extends Data = Data> = WithRef<
|
|
|
288
301
|
>;
|
|
289
302
|
|
|
290
303
|
/**
|
|
291
|
-
*
|
|
304
|
+
* 合并 FormItem 插槽与组件插槽
|
|
292
305
|
*/
|
|
293
306
|
export type MergeSlots<T, CS = ComponentSlots<T>> = Partial<{
|
|
294
307
|
[K in keyof FormItemSlots | keyof CS]: K extends keyof FormItemSlots
|
|
@@ -299,7 +312,8 @@ export type MergeSlots<T, CS = ComponentSlots<T>> = Partial<{
|
|
|
299
312
|
}>;
|
|
300
313
|
|
|
301
314
|
/**
|
|
302
|
-
*
|
|
315
|
+
* 从 Vue 组件提取 Props 与 Slots,并叠加公共字段属性
|
|
316
|
+
*
|
|
303
317
|
* @template T - Vue 组件类型
|
|
304
318
|
* @template D - 数据对象类型
|
|
305
319
|
*/
|
|
@@ -311,24 +325,29 @@ type WithComponent<T, D extends Data = Data> = Omit<
|
|
|
311
325
|
};
|
|
312
326
|
|
|
313
327
|
/**
|
|
314
|
-
*
|
|
328
|
+
* 字段配置类型,包含字段属性、响应式取值与宿主组件 Props
|
|
329
|
+
*
|
|
330
|
+
* @template C - 组件名,默认覆盖全部内置组件名
|
|
315
331
|
* @template D - 数据对象类型
|
|
316
|
-
|
|
332
|
+
*
|
|
317
333
|
* @public
|
|
318
334
|
*/
|
|
319
335
|
export type Field<
|
|
320
336
|
C extends ComponentName = ComponentName,
|
|
321
337
|
D extends Data = Data,
|
|
322
|
-
> =
|
|
338
|
+
> = (
|
|
323
339
|
| (FieldTypeMap<D>[C] & {
|
|
324
340
|
component?: C extends 'custom' ? FieldTypeMap<D>[C]['component'] : C;
|
|
325
341
|
})
|
|
326
|
-
| WithFields<D
|
|
342
|
+
| WithFields<D>
|
|
343
|
+
) &
|
|
344
|
+
AdditionalMethods<FormItemInstance>;
|
|
327
345
|
|
|
328
346
|
/**
|
|
329
|
-
*
|
|
347
|
+
* 字段配置数组类型
|
|
348
|
+
*
|
|
330
349
|
* @template D - 数据对象类型
|
|
331
|
-
|
|
350
|
+
*
|
|
332
351
|
* @public
|
|
333
352
|
*/
|
|
334
353
|
export type Fields<D extends Data = Data> = Array<Field<ComponentName, D>>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { toRaw } from 'vue';
|
|
2
|
+
|
|
3
|
+
const fieldKeyMap = new WeakMap<object, number>();
|
|
4
|
+
let fieldKeySeed = 0;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 字段渲染 key
|
|
8
|
+
*
|
|
9
|
+
* @description 以 `toRaw(field)` 为键在模块级 WeakMap 中缓存自增编号,同一字段对象恒得同一 key:
|
|
10
|
+
* key 与字段在数组中的位置解耦,字段插入 / 删除 / 重排 / 过滤后仍与对象绑定;同 `path` 的兄弟字段各得其唯一 key。
|
|
11
|
+
* 非对象项无对象身份,按字面量生成稳定 key;渲染路径传入的字段项已由调用方过滤为非 null 对象,
|
|
12
|
+
* 该分支供本模块的直接调用者使用
|
|
13
|
+
*
|
|
14
|
+
* @param field - 字段配置项
|
|
15
|
+
* @returns 字段渲染 key
|
|
16
|
+
*/
|
|
17
|
+
export const getFieldKey = (field: unknown): string | number => {
|
|
18
|
+
if (field === null || typeof field !== 'object')
|
|
19
|
+
return `raw_${String(field)}`;
|
|
20
|
+
const raw = toRaw(field);
|
|
21
|
+
let key = fieldKeyMap.get(raw);
|
|
22
|
+
if (key === undefined) {
|
|
23
|
+
key = ++fieldKeySeed;
|
|
24
|
+
fieldKeyMap.set(raw, key);
|
|
25
|
+
}
|
|
26
|
+
return key;
|
|
27
|
+
};
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
+
/**
|
|
3
|
+
* 列显隐控制控件,以下拉菜单列出可控列并支持全选/取消全选
|
|
4
|
+
*
|
|
5
|
+
* @component ColumnControl
|
|
6
|
+
*
|
|
7
|
+
* @param {Columns} columns - 参与控制的列配置(由 ProTable 下发)
|
|
8
|
+
* @param {Table} [table] - 表格实例,勾选结果经其 `setColumn` 写回列 `hidden`
|
|
9
|
+
* @param {ColumnControlConfig} [columnControl] - 控制项配置:labels / excludedKeys / disabledKeys / disableCheckAll
|
|
10
|
+
*/
|
|
2
11
|
import {
|
|
3
12
|
Button,
|
|
4
13
|
Dropdown,
|
|
@@ -6,12 +15,12 @@ import {
|
|
|
6
15
|
DropdownItem,
|
|
7
16
|
Checkbox,
|
|
8
17
|
} from '../../../shared/ui';
|
|
9
|
-
import { computed, ref, watch } from 'vue';
|
|
18
|
+
import { toValue, computed, ref, watch } from 'vue';
|
|
10
19
|
import type { Column, Columns, ColumnControlConfig } from '../types';
|
|
11
|
-
import { type Table } from '../
|
|
20
|
+
import { type Table } from '../hooks';
|
|
12
21
|
import FilterOutlined from './icons/FilterOutlined.vue';
|
|
13
22
|
import { useLocale } from '../../../locale';
|
|
14
|
-
import { normalizePathKey } from '../../../shared/core';
|
|
23
|
+
import { isObjectItem, normalizePathKey } from '../../../shared/core';
|
|
15
24
|
|
|
16
25
|
type Props = {
|
|
17
26
|
columns: Columns;
|
|
@@ -29,7 +38,8 @@ const checkAll = ref(false);
|
|
|
29
38
|
const indeterminate = ref(false);
|
|
30
39
|
|
|
31
40
|
const getColumnKey = (column: Column) => {
|
|
32
|
-
|
|
41
|
+
// 空字符串 key 视为未提供,回退 prop(与列渲染口径一致)
|
|
42
|
+
const rawKey = column.key || column.prop;
|
|
33
43
|
if (rawKey === undefined || rawKey === null || rawKey === '')
|
|
34
44
|
return undefined;
|
|
35
45
|
return normalizePathKey(rawKey);
|
|
@@ -44,7 +54,7 @@ const checkedColumnsOptions = computed<
|
|
|
44
54
|
column: Column;
|
|
45
55
|
}>
|
|
46
56
|
>(() =>
|
|
47
|
-
props.columns.flatMap(item => {
|
|
57
|
+
props.columns.filter(isObjectItem).flatMap(item => {
|
|
48
58
|
const key = getColumnKey(item);
|
|
49
59
|
// 无 key/prop 列不进入列控面板
|
|
50
60
|
if (key === undefined) return [];
|
|
@@ -72,7 +82,7 @@ const checkedColumnsOptions = computed<
|
|
|
72
82
|
return {
|
|
73
83
|
label,
|
|
74
84
|
value: key,
|
|
75
|
-
checked: !item.hidden || !!disabled,
|
|
85
|
+
checked: !toValue(item.hidden) || !!disabled,
|
|
76
86
|
disabled: !!disabled,
|
|
77
87
|
column: item,
|
|
78
88
|
};
|