@vue-ui-kit/ant 1.7.4 → 1.8.2
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/README.md +430 -233
- package/README.zh.md +446 -303
- package/dist/cjs/index.js +1 -1
- package/dist/declarations/antProxy.d.ts +7 -1
- package/dist/es/index.js +3038 -2244
- package/dist/index.d.ts +5 -1
- package/dist/packages/components/PFormCol.vue.d.ts +28 -0
- package/dist/packages/components/PFormGroup.vue.d.ts +2 -2
- package/dist/packages/components/PGrid.vue.d.ts +3 -2
- package/dist/packages/renders/TableInput.vue.d.ts +3 -3
- package/dist/packages/utils/config.d.ts +17 -0
- package/dist/packages/utils/core.d.ts +1 -1
- package/dist/style.css +1 -1
- package/package.json +3 -4
- package/src/declarations/antProxy.ts +8 -1
- package/src/index.ts +16 -0
- package/src/packages/components/PForm.vue +34 -85
- package/src/packages/components/PFormCol.vue +97 -0
- package/src/packages/components/PFormGroup.vue +90 -28
- package/src/packages/components/PGrid.vue +38 -81
- package/src/packages/renders/TableInput.vue +1 -1
- package/src/packages/store/renderStore.tsx +1 -1
- package/src/packages/styles/index.scss +80 -1
- package/src/packages/utils/AFormatters.ts +1 -1
- package/src/packages/utils/config.ts +72 -0
- package/src/packages/utils/core.ts +1 -1
package/README.zh.md
CHANGED
|
@@ -108,373 +108,516 @@ export const setupKit = () => {
|
|
|
108
108
|
|
|
109
109
|
## 组件
|
|
110
110
|
|
|
111
|
+
### PGrid
|
|
112
|
+
|
|
113
|
+
增强的数据表格组件,集成了查询表单、分页和工具栏功能。
|
|
114
|
+
|
|
115
|
+
#### 基础示例
|
|
116
|
+
|
|
117
|
+
```vue
|
|
118
|
+
<script setup lang="ts">
|
|
119
|
+
import { computed } from 'vue';
|
|
120
|
+
import { PGridProps, labelColDict } from '@vue-ui-kit/ant';
|
|
121
|
+
|
|
122
|
+
const gridSetting = computed<PGridProps<Student, { keyword?: string }>>(() => ({
|
|
123
|
+
columns: [
|
|
124
|
+
{ field: 'name', title: '姓名', width: 200 },
|
|
125
|
+
{ field: 'email', title: '邮箱', width: 200 },
|
|
126
|
+
{ field: 'age', title: '年龄', width: 100 },
|
|
127
|
+
],
|
|
128
|
+
formConfig: {
|
|
129
|
+
items: [
|
|
130
|
+
{
|
|
131
|
+
field: 'keyword',
|
|
132
|
+
title: '关键字',
|
|
133
|
+
labelCol: labelColDict[3],
|
|
134
|
+
itemRender: {
|
|
135
|
+
name: '$input',
|
|
136
|
+
props: { placeholder: '请输入关键字...' },
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
},
|
|
141
|
+
proxyConfig: {
|
|
142
|
+
ajax: {
|
|
143
|
+
query: ({ form, page }) => api.getStudents({ ...form, ...page }),
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
}));
|
|
147
|
+
</script>
|
|
148
|
+
|
|
149
|
+
<template>
|
|
150
|
+
<p-grid v-bind="gridSetting" />
|
|
151
|
+
</template>
|
|
152
|
+
```
|
|
153
|
+
|
|
111
154
|
### PForm
|
|
112
155
|
|
|
113
156
|
增强的表单组件,具有简化的配置和动态字段功能。
|
|
114
157
|
|
|
115
158
|
#### 属性
|
|
116
159
|
|
|
117
|
-
| 属性
|
|
118
|
-
|
|
|
119
|
-
| items
|
|
120
|
-
|
|
|
121
|
-
|
|
|
160
|
+
| 属性 | 类型 | 说明 | 默认值 |
|
|
161
|
+
| --- | --- | --- | --- |
|
|
162
|
+
| items | `PFormItemProps[]` | 表单项配置数组 | - |
|
|
163
|
+
| data | `T` | 表单数据对象 | - |
|
|
164
|
+
| customReset | `() => void` | 自定义重置函数 | - |
|
|
165
|
+
| labelCol | `ColProps` | 标签列布局 | `{ span: 6 }` |
|
|
166
|
+
| wrapperCol | `ColProps` | 包装列布局 | `{ span: 16 }` |
|
|
167
|
+
| ...其他 | `FormProps` | 所有 ant-design-vue Form 的属性 | - |
|
|
168
|
+
|
|
169
|
+
#### 事件
|
|
170
|
+
|
|
171
|
+
| 事件 | 说明 | 参数 |
|
|
172
|
+
| --- | --- | --- |
|
|
173
|
+
| apply | 表单提交时触发 | `(formData: T) => void` |
|
|
174
|
+
| reset | 表单重置时触发 | `() => void` |
|
|
122
175
|
|
|
123
176
|
#### PFormItemProps
|
|
124
177
|
|
|
125
|
-
| 属性
|
|
126
|
-
|
|
|
127
|
-
| field
|
|
128
|
-
| title
|
|
129
|
-
| span
|
|
130
|
-
| colon
|
|
131
|
-
|
|
|
132
|
-
|
|
|
133
|
-
|
|
|
134
|
-
|
|
|
135
|
-
|
|
|
178
|
+
| 属性 | 类型 | 说明 | 默认值 |
|
|
179
|
+
| --- | --- | --- | --- |
|
|
180
|
+
| field | `string` | 表单字段名 | - |
|
|
181
|
+
| title | `string` | 字段标签 | - |
|
|
182
|
+
| span | `number` | 栅格跨度 (1-24) | - |
|
|
183
|
+
| colon | `boolean` | 标签后显示冒号 | `true` |
|
|
184
|
+
| labelCol | `ColProps` | 标签列布局 | - |
|
|
185
|
+
| wrapperCol | `ColProps` | 包装列布局 | - |
|
|
186
|
+
| forceRequired | `boolean` | 显示必填标记(仅视觉效果) | `false` |
|
|
187
|
+
| align | `'left' \| 'right' \| 'center'` | 文本对齐方式 | `'left'` |
|
|
188
|
+
| col | `ColProps` | 栅格列属性 | - |
|
|
189
|
+
| rule | `Rule[]` | 验证规则 | - |
|
|
190
|
+
| itemRender | `ItemRender` | 字段渲染器配置 | - |
|
|
191
|
+
| tooltipConfig | `TooltipConfig` | 提示配置 | - |
|
|
192
|
+
| slots | `object` | 自定义插槽渲染器 | - |
|
|
193
|
+
|
|
194
|
+
#### 内置渲染器
|
|
195
|
+
|
|
196
|
+
- `$input`: 输入框
|
|
197
|
+
- `$textarea`: 文本域
|
|
198
|
+
- `$number`: 数字输入框
|
|
199
|
+
- `$select`: 下拉选择
|
|
200
|
+
- `$date`: 日期选择器
|
|
201
|
+
- `$range`: 日期范围选择器
|
|
202
|
+
- `$time`: 时间选择器
|
|
203
|
+
- `ASwitch`: 开关组件
|
|
204
|
+
- `ACheckbox`: 复选框
|
|
205
|
+
- `ARate`: 评分组件
|
|
206
|
+
- `ASlider`: 滑动输入条
|
|
207
|
+
|
|
208
|
+
#### 基础示例
|
|
136
209
|
|
|
137
|
-
|
|
210
|
+
```vue
|
|
211
|
+
<script setup lang="ts">
|
|
212
|
+
import { ref, computed } from 'vue';
|
|
213
|
+
import { PFormProps } from '@vue-ui-kit/ant';
|
|
214
|
+
|
|
215
|
+
interface UserForm {
|
|
216
|
+
name: string;
|
|
217
|
+
email: string;
|
|
218
|
+
age?: number;
|
|
219
|
+
gender: string;
|
|
220
|
+
skills: string[];
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const formData = ref<UserForm>({
|
|
224
|
+
name: '',
|
|
225
|
+
email: '',
|
|
226
|
+
age: undefined,
|
|
227
|
+
gender: '',
|
|
228
|
+
skills: [],
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
const formSetting = computed<PFormProps<UserForm>>(() => ({
|
|
232
|
+
items: [
|
|
233
|
+
{
|
|
234
|
+
field: 'name',
|
|
235
|
+
title: '姓名',
|
|
236
|
+
span: 12,
|
|
237
|
+
rule: [{ required: true, message: '请输入姓名' }],
|
|
238
|
+
itemRender: {
|
|
239
|
+
name: '$input',
|
|
240
|
+
props: { placeholder: '请输入姓名' },
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
field: 'email',
|
|
245
|
+
title: '邮箱',
|
|
246
|
+
span: 12,
|
|
247
|
+
rule: [
|
|
248
|
+
{ required: true, message: '请输入邮箱' },
|
|
249
|
+
{ type: 'email', message: '邮箱格式不正确' },
|
|
250
|
+
],
|
|
251
|
+
itemRender: {
|
|
252
|
+
name: '$input',
|
|
253
|
+
props: { placeholder: '请输入邮箱' },
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
field: 'gender',
|
|
258
|
+
title: '性别',
|
|
259
|
+
span: 12,
|
|
260
|
+
rule: [{ required: true, message: '请选择性别' }],
|
|
261
|
+
itemRender: {
|
|
262
|
+
name: '$select',
|
|
263
|
+
props: {
|
|
264
|
+
placeholder: '请选择性别',
|
|
265
|
+
options: [
|
|
266
|
+
{ label: '男', value: 'male' },
|
|
267
|
+
{ label: '女', value: 'female' },
|
|
268
|
+
],
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
field: 'skills',
|
|
274
|
+
title: '技能',
|
|
275
|
+
span: 24,
|
|
276
|
+
itemRender: {
|
|
277
|
+
name: '$select',
|
|
278
|
+
props: {
|
|
279
|
+
mode: 'multiple',
|
|
280
|
+
placeholder: '请选择技能',
|
|
281
|
+
options: [
|
|
282
|
+
{ label: 'Vue.js', value: 'vue' },
|
|
283
|
+
{ label: 'React', value: 'react' },
|
|
284
|
+
{ label: 'Angular', value: 'angular' },
|
|
285
|
+
],
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
],
|
|
290
|
+
}));
|
|
291
|
+
|
|
292
|
+
const handleSubmit = (data: UserForm) => {
|
|
293
|
+
console.log('表单提交:', data);
|
|
294
|
+
};
|
|
295
|
+
</script>
|
|
296
|
+
|
|
297
|
+
<template>
|
|
298
|
+
<p-form
|
|
299
|
+
v-bind="formSetting"
|
|
300
|
+
:data="formData"
|
|
301
|
+
@apply="handleSubmit"
|
|
302
|
+
/>
|
|
303
|
+
</template>
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
#### 自定义插槽示例
|
|
138
307
|
|
|
139
308
|
```vue
|
|
140
309
|
<script setup lang="tsx">
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
310
|
+
import { ref, computed } from 'vue';
|
|
311
|
+
|
|
312
|
+
const formData = ref({
|
|
313
|
+
name: '',
|
|
314
|
+
isActive: false,
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
const formSetting = computed(() => ({
|
|
318
|
+
items: [
|
|
319
|
+
{
|
|
320
|
+
field: 'isActive',
|
|
321
|
+
title: '状态',
|
|
322
|
+
span: 24,
|
|
323
|
+
slots: {
|
|
324
|
+
default: ({ data }) => (
|
|
325
|
+
<a-switch
|
|
326
|
+
v-model:checked={data.isActive}
|
|
327
|
+
checkedChildren="启用"
|
|
328
|
+
unCheckedChildren="禁用"
|
|
329
|
+
/>
|
|
330
|
+
),
|
|
331
|
+
},
|
|
157
332
|
},
|
|
333
|
+
],
|
|
334
|
+
}));
|
|
335
|
+
</script>
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### PFormGroup
|
|
339
|
+
|
|
340
|
+
动态表单组组件,用于管理多个表单实例,支持添加/删除功能。
|
|
341
|
+
|
|
342
|
+
#### 属性
|
|
343
|
+
|
|
344
|
+
| 属性 | 类型 | 说明 | 默认值 |
|
|
345
|
+
| --- | --- | --- | --- |
|
|
346
|
+
| v-model | `Array<T & { __index: number }>` | 表单组数据数组 | `[]` |
|
|
347
|
+
| getFormSetting | `(data: T) => PFormProps<T>` | 获取表单配置的函数 | - |
|
|
348
|
+
| title | `string` | 组标题 | - |
|
|
349
|
+
| tabLabel | `string` | 自定义标签页标签模板 | - |
|
|
350
|
+
| editAble | `boolean` | 标签页是否可编辑 | `true` |
|
|
351
|
+
| showAdd | `boolean` | 显示添加按钮 | `true` |
|
|
352
|
+
| lazyErrorMark | `boolean` | 延迟错误标记 | `false` |
|
|
353
|
+
| forceRender | `boolean` | 强制渲染所有标签页 | `false` |
|
|
354
|
+
| keepSerial | `boolean` | 保持连续编号 | `false` |
|
|
355
|
+
| loading | `boolean` | 加载状态 | `false` |
|
|
356
|
+
| max | `number` | 最大项目数量 | `Infinity` |
|
|
357
|
+
| itemMenus | `GroupMenuItem[]` | 自定义菜单项 | 默认复制/删除 |
|
|
358
|
+
| createItem | `(opts: { list: T[] }) => Promise<T>` | 自定义项目创建器 | - |
|
|
359
|
+
| menuHandler | `GroupMenuItemHandler<T>` | 自定义菜单处理器 | - |
|
|
360
|
+
|
|
361
|
+
#### 暴露的方法
|
|
362
|
+
|
|
363
|
+
| 方法 | 说明 | 参数 | 返回值 |
|
|
364
|
+
| --- | --- | --- | --- |
|
|
365
|
+
| validateAll | 验证所有表单实例 | - | `Promise<void>` |
|
|
366
|
+
| validate | 验证特定表单实例 | `__index: number` | `Promise<void>` |
|
|
367
|
+
| setActiveKey | 设置活动标签页 | `key: number` | `void` |
|
|
368
|
+
|
|
369
|
+
#### 基础示例
|
|
370
|
+
|
|
371
|
+
```vue
|
|
372
|
+
<script setup lang="ts">
|
|
373
|
+
import { ref, computed } from 'vue';
|
|
374
|
+
import { PFormGroupProps } from '@vue-ui-kit/ant';
|
|
375
|
+
|
|
376
|
+
interface Project {
|
|
377
|
+
__index: number;
|
|
378
|
+
name: string;
|
|
379
|
+
startDate: string;
|
|
380
|
+
endDate: string;
|
|
381
|
+
budget?: number;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const projects = ref<Project[]>([
|
|
385
|
+
{
|
|
386
|
+
__index: 0,
|
|
387
|
+
name: '项目A',
|
|
388
|
+
startDate: '',
|
|
389
|
+
endDate: '',
|
|
390
|
+
budget: undefined,
|
|
391
|
+
}
|
|
392
|
+
]);
|
|
393
|
+
|
|
394
|
+
const groupSetting = computed<PFormGroupProps<Project>>(() => ({
|
|
395
|
+
title: '项目管理',
|
|
396
|
+
showAdd: true,
|
|
397
|
+
max: 10,
|
|
398
|
+
getFormSetting: (data) => ({
|
|
158
399
|
items: [
|
|
159
400
|
{
|
|
160
|
-
|
|
401
|
+
field: 'name',
|
|
402
|
+
title: '项目名称',
|
|
161
403
|
span: 24,
|
|
404
|
+
rule: [{ required: true, message: '请输入项目名称' }],
|
|
162
405
|
itemRender: {
|
|
163
|
-
name: '
|
|
164
|
-
props: {
|
|
165
|
-
getText: () => 'Test',
|
|
166
|
-
},
|
|
406
|
+
name: '$input',
|
|
407
|
+
props: { placeholder: '请输入项目名称' },
|
|
167
408
|
},
|
|
168
409
|
},
|
|
169
410
|
{
|
|
170
|
-
field: '
|
|
171
|
-
title: '
|
|
172
|
-
span:
|
|
411
|
+
field: 'startDate',
|
|
412
|
+
title: '开始日期',
|
|
413
|
+
span: 12,
|
|
414
|
+
rule: [{ required: true, message: '请选择开始日期' }],
|
|
173
415
|
itemRender: {
|
|
174
|
-
name: '$
|
|
175
|
-
props: {
|
|
176
|
-
options: [
|
|
177
|
-
{ label: 'Test账户1', value: '1' },
|
|
178
|
-
{ label: 'Test账户2', value: '2' },
|
|
179
|
-
],
|
|
180
|
-
},
|
|
181
|
-
events: {
|
|
182
|
-
change: ({ data }) => {
|
|
183
|
-
data.org_id = '';
|
|
184
|
-
},
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
tooltipConfig: {
|
|
188
|
-
title: '账号是指登录Test后台的邮箱',
|
|
416
|
+
name: '$date',
|
|
417
|
+
props: { placeholder: '请选择开始日期' },
|
|
189
418
|
},
|
|
190
419
|
},
|
|
191
420
|
{
|
|
192
|
-
field: '
|
|
193
|
-
title: '
|
|
194
|
-
span:
|
|
195
|
-
|
|
196
|
-
default: ({ data }) => <my-custom-input v-model={data.org_id}></my-custom-input>,
|
|
197
|
-
},
|
|
198
|
-
tooltipConfig: {
|
|
199
|
-
title: '对应账号下的组织名称、组织ID、组织核心ID(Org Core ID)',
|
|
200
|
-
},
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
field: 'secret_key',
|
|
204
|
-
title: 'Secret Key',
|
|
205
|
-
span: 24,
|
|
421
|
+
field: 'endDate',
|
|
422
|
+
title: '结束日期',
|
|
423
|
+
span: 12,
|
|
424
|
+
rule: [{ required: true, message: '请选择结束日期' }],
|
|
206
425
|
itemRender: {
|
|
207
|
-
name: '$
|
|
208
|
-
|
|
209
|
-
tooltipConfig: {
|
|
210
|
-
title: '我是tooltip',
|
|
426
|
+
name: '$date',
|
|
427
|
+
props: { placeholder: '请选择结束日期' },
|
|
211
428
|
},
|
|
212
429
|
},
|
|
213
430
|
{
|
|
214
|
-
field: '
|
|
215
|
-
title: '
|
|
431
|
+
field: 'budget',
|
|
432
|
+
title: '预算',
|
|
216
433
|
span: 24,
|
|
217
434
|
itemRender: {
|
|
218
|
-
name: '$
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
435
|
+
name: '$number',
|
|
436
|
+
props: {
|
|
437
|
+
min: 0,
|
|
438
|
+
placeholder: '请输入预算',
|
|
439
|
+
formatter: (value) => `¥ ${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ','),
|
|
440
|
+
parser: (value) => value.replace(/¥\s?|(,*)/g, ''),
|
|
441
|
+
},
|
|
222
442
|
},
|
|
223
443
|
},
|
|
224
444
|
],
|
|
225
|
-
})
|
|
445
|
+
}),
|
|
446
|
+
}));
|
|
447
|
+
|
|
448
|
+
const handleSave = async () => {
|
|
449
|
+
try {
|
|
450
|
+
await groupRef.value?.validateAll();
|
|
451
|
+
console.log('所有项目已保存:', projects.value);
|
|
452
|
+
} catch (error) {
|
|
453
|
+
console.error('验证失败:', error);
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
|
|
457
|
+
const groupRef = ref();
|
|
226
458
|
</script>
|
|
459
|
+
|
|
227
460
|
<template>
|
|
228
|
-
<
|
|
461
|
+
<div>
|
|
462
|
+
<p-form-group
|
|
463
|
+
ref="groupRef"
|
|
464
|
+
v-model="projects"
|
|
465
|
+
v-bind="groupSetting"
|
|
466
|
+
/>
|
|
467
|
+
<a-button type="primary" @click="handleSave">
|
|
468
|
+
保存所有项目
|
|
469
|
+
</a-button>
|
|
470
|
+
</div>
|
|
229
471
|
</template>
|
|
230
472
|
```
|
|
231
473
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
高级表格组件,内置数据管理和工具栏功能。
|
|
235
|
-
|
|
236
|
-
#### 属性
|
|
237
|
-
|
|
238
|
-
| 属性 | 类型 | 说明 | 默认值 |
|
|
239
|
-
| ------------- | -------------------- | -------------- | ------- |
|
|
240
|
-
| rowKey | `string` | 唯一标识字段 | 'id' |
|
|
241
|
-
| columns | `ColumnProps[]` | 表格列配置 | - |
|
|
242
|
-
| formConfig | `PFormProps` | 搜索表单配置 | - |
|
|
243
|
-
| toolbarConfig | `ToolbarConfig` | 工具栏按钮配置 | - |
|
|
244
|
-
| pageConfig | `PageConfig` | 分页配置 | - |
|
|
245
|
-
| proxyConfig | `ProxyConfig` | 数据获取配置 | - |
|
|
246
|
-
| selectConfig | `SelectConfig` | 行选择配置 | - |
|
|
247
|
-
| scrollMode | `'outer' \| 'inner'` | 滚动模式 | 'outer' |
|
|
248
|
-
| fitHeight | `number` | 自适应高度调整 | - |
|
|
249
|
-
|
|
250
|
-
#### 示例
|
|
474
|
+
#### 自定义菜单示例
|
|
251
475
|
|
|
252
476
|
```vue
|
|
253
477
|
<script setup lang="ts">
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
},
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
content: t('批量删除'),
|
|
269
|
-
type: 'danger',
|
|
270
|
-
},
|
|
271
|
-
],
|
|
272
|
-
},
|
|
273
|
-
columns: [
|
|
274
|
-
{
|
|
275
|
-
field: 'id',
|
|
276
|
-
title: 'ID',
|
|
277
|
-
width: 110,
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
field: 'name',
|
|
281
|
-
title: '渠道名称',
|
|
282
|
-
width: 140,
|
|
283
|
-
},
|
|
284
|
-
{
|
|
285
|
-
field: 'short_name',
|
|
286
|
-
title: '简称',
|
|
287
|
-
width: 140,
|
|
288
|
-
},
|
|
289
|
-
{
|
|
290
|
-
field: 'operator',
|
|
291
|
-
title: '操作人',
|
|
292
|
-
width: 120,
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
field: 'update_time',
|
|
296
|
-
title: '最近修改时间',
|
|
297
|
-
width: 180,
|
|
298
|
-
},
|
|
299
|
-
...(hasAuth('common_channel_admin')
|
|
300
|
-
? ([
|
|
301
|
-
{
|
|
302
|
-
title: '操作',
|
|
303
|
-
fixed: 'right',
|
|
304
|
-
width: 160,
|
|
305
|
-
cellRender: {
|
|
306
|
-
name: 'ButtonTree',
|
|
307
|
-
children: [
|
|
308
|
-
{
|
|
309
|
-
content: '编辑',
|
|
310
|
-
type: 'link',
|
|
311
|
-
clickEvt: ({ row }: { row: Channel }) => doEdit(row),
|
|
312
|
-
},
|
|
313
|
-
{
|
|
314
|
-
content: '删除',
|
|
315
|
-
type: 'link',
|
|
316
|
-
danger: true,
|
|
317
|
-
clickEvt: ({ row }: { row: Channel }) => confirmDelete(row),
|
|
318
|
-
},
|
|
319
|
-
],
|
|
320
|
-
},
|
|
321
|
-
},
|
|
322
|
-
] as ColumnProps<Channel>[])
|
|
323
|
-
: []),
|
|
324
|
-
],
|
|
325
|
-
formConfig: {
|
|
326
|
-
items: [
|
|
327
|
-
{
|
|
328
|
-
field: 'name',
|
|
329
|
-
title: '渠道名称',
|
|
330
|
-
labelCol: labelColDict[4],
|
|
331
|
-
itemRender: {
|
|
332
|
-
name: '$input',
|
|
333
|
-
props: {
|
|
334
|
-
placeholder: '请输入广告渠道名称',
|
|
335
|
-
},
|
|
336
|
-
},
|
|
337
|
-
},
|
|
338
|
-
{
|
|
339
|
-
col: getButtonResponsive(1),
|
|
340
|
-
align: 'right',
|
|
341
|
-
itemRender: {
|
|
342
|
-
name: '$buttons',
|
|
343
|
-
children: [
|
|
344
|
-
{
|
|
345
|
-
props: {
|
|
346
|
-
content: '查询',
|
|
347
|
-
htmlType: 'submit',
|
|
348
|
-
type: 'primary',
|
|
349
|
-
},
|
|
350
|
-
},
|
|
351
|
-
{
|
|
352
|
-
props: {
|
|
353
|
-
content: '重置',
|
|
354
|
-
htmlType: 'reset',
|
|
355
|
-
},
|
|
356
|
-
},
|
|
357
|
-
],
|
|
358
|
-
},
|
|
359
|
-
},
|
|
360
|
-
],
|
|
361
|
-
},
|
|
362
|
-
pageConfig: {
|
|
363
|
-
pageSize: 10,
|
|
364
|
-
},
|
|
365
|
-
proxyConfig: {
|
|
366
|
-
response: {
|
|
367
|
-
total: 'total',
|
|
368
|
-
result: 'list',
|
|
369
|
-
},
|
|
370
|
-
ajax: {
|
|
371
|
-
query: ({ form, page }) =>
|
|
372
|
-
getChannelPage({
|
|
373
|
-
...form,
|
|
374
|
-
...page,
|
|
375
|
-
} as ChannelParam),
|
|
376
|
-
multiDelete: deleteChannels,
|
|
377
|
-
},
|
|
478
|
+
import { ref, computed } from 'vue';
|
|
479
|
+
|
|
480
|
+
const projects = ref([]);
|
|
481
|
+
|
|
482
|
+
const groupSetting = computed(() => ({
|
|
483
|
+
title: '高级项目管理',
|
|
484
|
+
itemMenus: [
|
|
485
|
+
{ content: '复制', code: 'copy' },
|
|
486
|
+
{ content: '删除', code: 'delete' },
|
|
487
|
+
{ content: '导出', code: 'export' },
|
|
488
|
+
{
|
|
489
|
+
content: '归档',
|
|
490
|
+
code: 'archive',
|
|
491
|
+
visibleMethod: ({ data }) => data.status !== 'archived'
|
|
378
492
|
},
|
|
379
|
-
|
|
493
|
+
],
|
|
494
|
+
createItem: async ({ list }) => {
|
|
495
|
+
return {
|
|
496
|
+
name: `项目 ${list.length + 1}`,
|
|
497
|
+
status: 'active',
|
|
498
|
+
startDate: new Date().toISOString().split('T')[0],
|
|
499
|
+
};
|
|
500
|
+
},
|
|
501
|
+
menuHandler: ({ code, data, index }) => {
|
|
502
|
+
switch (code) {
|
|
503
|
+
case 'export':
|
|
504
|
+
exportProject(data);
|
|
505
|
+
break;
|
|
506
|
+
case 'archive':
|
|
507
|
+
archiveProject(data, index);
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
},
|
|
511
|
+
getFormSetting: (data) => ({
|
|
512
|
+
// ... 表单配置
|
|
513
|
+
}),
|
|
514
|
+
}));
|
|
380
515
|
</script>
|
|
381
|
-
<template>
|
|
382
|
-
<p-grid ref="gridEl" v-bind="gridSetting" />
|
|
383
|
-
</template>
|
|
384
516
|
```
|
|
385
517
|
|
|
386
|
-
|
|
518
|
+
## 工具函数
|
|
387
519
|
|
|
388
|
-
|
|
520
|
+
### labelColDict
|
|
389
521
|
|
|
390
|
-
|
|
522
|
+
为不同文本长度预定义的标签列配置:
|
|
391
523
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
524
|
+
```ts
|
|
525
|
+
import { labelColDict } from '@vue-ui-kit/ant';
|
|
526
|
+
|
|
527
|
+
// 在表单项中使用
|
|
528
|
+
{
|
|
529
|
+
field: 'shortField',
|
|
530
|
+
title: '姓名', // 2个字符
|
|
531
|
+
labelCol: labelColDict[2],
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
{
|
|
535
|
+
field: 'longerField',
|
|
536
|
+
title: '项目描述', // 4+个字符
|
|
537
|
+
labelCol: labelColDict[4],
|
|
538
|
+
}
|
|
539
|
+
```
|
|
396
540
|
|
|
397
|
-
|
|
541
|
+
### 自定义渲染器
|
|
398
542
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
543
|
+
注册自定义表单字段渲染器:
|
|
544
|
+
|
|
545
|
+
```tsx
|
|
546
|
+
import UIKit from '@vue-ui-kit/ant';
|
|
547
|
+
import { Switch } from 'ant-design-vue';
|
|
548
|
+
|
|
549
|
+
UIKit.addRender('$switch', {
|
|
550
|
+
renderItemContent(
|
|
551
|
+
{ props = {}, events = {} },
|
|
552
|
+
{ data, field }
|
|
553
|
+
) {
|
|
554
|
+
return (
|
|
555
|
+
<Switch
|
|
556
|
+
v-model:checked={data[field]}
|
|
557
|
+
{...props}
|
|
558
|
+
onChange={(...args) => {
|
|
559
|
+
events.change?.({ data, field }, ...args);
|
|
560
|
+
}}
|
|
561
|
+
/>
|
|
562
|
+
);
|
|
563
|
+
},
|
|
564
|
+
});
|
|
419
565
|
```
|
|
420
566
|
|
|
421
|
-
###
|
|
567
|
+
### 自定义格式化器
|
|
422
568
|
|
|
423
|
-
|
|
569
|
+
为 PGrid 注册自定义单元格格式化器:
|
|
424
570
|
|
|
425
|
-
|
|
571
|
+
```ts
|
|
572
|
+
UIKit.addFormatter({
|
|
573
|
+
currency: ({ cellValue }) => `¥${cellValue?.toLocaleString() || '0'}`,
|
|
574
|
+
percentage: ({ cellValue }) => `${(cellValue * 100).toFixed(2)}%`,
|
|
575
|
+
});
|
|
576
|
+
```
|
|
426
577
|
|
|
427
|
-
|
|
428
|
-
| ----------- | ------------------ | ---------- |
|
|
429
|
-
| gridSetting | `PGridProps` | 表格配置 |
|
|
430
|
-
| title | `string` | 模态框标题 |
|
|
431
|
-
| width | `string \| number` | 模态框宽度 |
|
|
578
|
+
## 常见问题
|
|
432
579
|
|
|
433
|
-
|
|
580
|
+
### 1. 使用 computed + v-bind 生成动态表格+表单时,表单选项更新导致表格重新渲染,如何解决?
|
|
581
|
+
|
|
582
|
+
答案:将 formConfig 分离为另一个计算属性
|
|
434
583
|
|
|
435
584
|
```vue
|
|
436
|
-
<
|
|
437
|
-
import { ref } from 'vue';
|
|
438
|
-
import { PromisePickerInstance } from '@vue-ui-kit/ant';
|
|
439
|
-
import { Asset } from '...somewhere';
|
|
440
|
-
import { fetchUsers } from '...somewhere';
|
|
441
|
-
|
|
442
|
-
const pickerEl = ref<PromisePickerInstance<Asset>>();
|
|
443
|
-
const test = () => {
|
|
444
|
-
pickerEl.value!.pick().then(({ row }) => {
|
|
445
|
-
console.log(row);
|
|
446
|
-
});
|
|
447
|
-
};
|
|
448
|
-
</script>
|
|
449
|
-
<template>
|
|
450
|
-
<promise-picker
|
|
451
|
-
ref="pickerEl"
|
|
452
|
-
title="选择用户"
|
|
453
|
-
:grid-setting="{
|
|
454
|
-
columns: [
|
|
455
|
-
{ title: '姓名', field: 'name' },
|
|
456
|
-
{ title: '邮箱', field: 'email' },
|
|
457
|
-
],
|
|
458
|
-
proxyConfig: {
|
|
459
|
-
ajax: {
|
|
460
|
-
query: fetchUsers,
|
|
461
|
-
},
|
|
462
|
-
},
|
|
463
|
-
}"
|
|
464
|
-
/>
|
|
465
|
-
</template>
|
|
585
|
+
<p-grid v-bind="gridSetting" :form-config="computedFormConfig" />
|
|
466
586
|
```
|
|
467
587
|
|
|
468
|
-
|
|
588
|
+
### 2. 表格 ajax 目前只支持 multiDelete 和表格数据获取吗?
|
|
589
|
+
|
|
590
|
+
答案:编辑详情在大多数情况下无法与表格一一对应,所以没有开发意义。多行删除需要配合使用:
|
|
469
591
|
|
|
470
|
-
|
|
592
|
+
```ts
|
|
593
|
+
selectConfig: {
|
|
594
|
+
multiple: true,
|
|
595
|
+
},
|
|
596
|
+
toolbarConfig: {
|
|
597
|
+
buttons: {
|
|
598
|
+
code: "multipleDelete"
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
```
|
|
471
602
|
|
|
472
|
-
|
|
603
|
+
### 3. 为什么推荐 computed 方式?
|
|
473
604
|
|
|
474
|
-
|
|
605
|
+
答案:它简化了所有动态逻辑。对于复杂场景,您可以尝试使用 reactive 并自己维护,但在大多数情况下,computed 更方便。
|
|
475
606
|
|
|
476
|
-
|
|
607
|
+
## TypeScript 支持
|
|
608
|
+
|
|
609
|
+
该库完全使用 TypeScript 编写,并提供全面的类型定义:
|
|
610
|
+
|
|
611
|
+
```ts
|
|
612
|
+
import type {
|
|
613
|
+
PFormProps,
|
|
614
|
+
PFormItemProps,
|
|
615
|
+
PFormGroupProps,
|
|
616
|
+
PGridProps,
|
|
617
|
+
ColumnProps
|
|
618
|
+
} from '@vue-ui-kit/ant';
|
|
619
|
+
```
|
|
477
620
|
|
|
478
|
-
|
|
621
|
+
## 许可证
|
|
479
622
|
|
|
480
|
-
|
|
623
|
+
MIT
|