@qin-ui/antd-vue-pro 2.1.14 → 2.2.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 +208 -95
- package/LICENSE +9 -0
- package/api.json +40 -29
- package/bin/init-ai.mjs +212 -52
- package/es/antd-vue-pro.css +9 -9
- package/es/component-provider/{index-Dmz32tSB.js → index-PHCLwRXW.js} +5 -4
- package/es/component-provider/index-PHCLwRXW.js.map +1 -0
- package/es/component-provider/index.js +2 -1
- package/es/component-provider/index.js.map +1 -0
- package/es/components/component-provider/components/index.vue.d.ts +35 -0
- package/es/components/component-provider/components/index.vue.d.ts.map +1 -0
- package/es/components/component-provider/constants/index.d.ts +16 -0
- package/es/components/component-provider/constants/index.d.ts.map +1 -0
- package/es/components/component-provider/index.d.ts +4 -0
- package/es/components/component-provider/index.d.ts.map +1 -0
- package/es/components/component-provider/types/index.d.ts +63 -0
- package/es/components/component-provider/types/index.d.ts.map +1 -0
- package/es/components/form/components/BaseField/index.vue.d.ts +13 -0
- package/es/components/form/components/BaseField/index.vue.d.ts.map +1 -0
- package/es/components/form/components/BaseField/utils/index.d.ts +3 -0
- package/es/components/form/components/BaseField/utils/index.d.ts.map +1 -0
- package/es/components/form/components/BaseFormItem/index.vue.d.ts +9 -0
- package/es/components/form/components/BaseFormItem/index.vue.d.ts.map +1 -0
- package/es/components/form/components/ContainerFragment/index.vue.d.ts +23 -0
- package/es/components/form/components/ContainerFragment/index.vue.d.ts.map +1 -0
- package/es/components/form/components/GroupedFieldAttrs/index.vue.d.ts +29 -0
- package/es/components/form/components/GroupedFieldAttrs/index.vue.d.ts.map +1 -0
- package/es/components/form/components/PathProvider/index.vue.d.ts +24 -0
- package/es/components/form/components/PathProvider/index.vue.d.ts.map +1 -0
- package/es/components/form/components/ProForm/index.vue.d.ts +36 -0
- package/es/components/form/components/ProForm/index.vue.d.ts.map +1 -0
- package/es/components/form/components/SlotComponent/index.vue.d.ts +7 -0
- package/es/components/form/components/SlotComponent/index.vue.d.ts.map +1 -0
- package/es/components/form/components/index.d.ts +12 -0
- package/es/components/form/components/index.d.ts.map +1 -0
- package/es/components/form/constants/index.d.ts +78 -0
- package/es/components/form/constants/index.d.ts.map +1 -0
- package/es/components/form/hooks/index.d.ts +5 -0
- package/es/components/form/hooks/index.d.ts.map +1 -0
- package/es/components/form/hooks/useFields.d.ts +57 -0
- package/es/components/form/hooks/useFields.d.ts.map +1 -0
- package/es/components/form/hooks/useForm.d.ts +93 -0
- package/es/components/form/hooks/useForm.d.ts.map +1 -0
- package/es/components/form/hooks/useFormRef.d.ts +30 -0
- package/es/components/form/hooks/useFormRef.d.ts.map +1 -0
- package/es/components/form/index.d.ts +7 -0
- package/es/components/form/index.d.ts.map +1 -0
- package/es/components/form/types/index.d.ts +207 -0
- package/es/components/form/types/index.d.ts.map +1 -0
- package/es/components/table/components/ColumnControl.vue.d.ts +9 -0
- package/es/components/table/components/ColumnControl.vue.d.ts.map +1 -0
- package/es/components/table/components/DefaultSearchFormContainer.vue.d.ts +18 -0
- package/es/components/table/components/DefaultSearchFormContainer.vue.d.ts.map +1 -0
- package/es/components/table/components/DefaultTableContainer.vue.d.ts +18 -0
- package/es/components/table/components/DefaultTableContainer.vue.d.ts.map +1 -0
- package/es/components/table/components/ProTable.vue.d.ts +100 -0
- package/es/components/table/components/ProTable.vue.d.ts.map +1 -0
- package/es/components/table/components/SearchForm.vue.d.ts +48 -0
- package/es/components/table/components/SearchForm.vue.d.ts.map +1 -0
- package/es/components/table/components/SizeControl.vue.d.ts +12 -0
- package/es/components/table/components/SizeControl.vue.d.ts.map +1 -0
- package/es/components/table/components/icons/ColumnHeightOutlined.vue.d.ts +3 -0
- package/es/components/table/components/icons/ColumnHeightOutlined.vue.d.ts.map +1 -0
- package/es/components/table/components/icons/DownOutlined.vue.d.ts +3 -0
- package/es/components/table/components/icons/DownOutlined.vue.d.ts.map +1 -0
- package/es/components/table/components/icons/FilterOutlined.vue.d.ts +3 -0
- package/es/components/table/components/icons/FilterOutlined.vue.d.ts.map +1 -0
- package/es/components/table/components/index.d.ts +5 -0
- package/es/components/table/components/index.d.ts.map +1 -0
- 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/hooks/useTable.d.ts +112 -0
- package/es/components/table/hooks/useTable.d.ts.map +1 -0
- package/es/components/table/index.d.ts +8 -0
- package/es/components/table/index.d.ts.map +1 -0
- package/es/components/table/types/index.d.ts +70 -0
- package/es/components/table/types/index.d.ts.map +1 -0
- package/es/form/index.js +14 -8
- package/es/form/index.js.map +1 -0
- package/es/index.d.ts +76 -1622
- package/es/index.d.ts.map +1 -0
- package/es/index.js +12 -22
- package/es/index.js.map +1 -0
- package/es/shared/core/index.d.ts +6 -0
- package/es/shared/core/index.d.ts.map +1 -0
- package/es/shared/ui/index.d.ts +15 -0
- package/es/shared/ui/index.d.ts.map +1 -0
- package/es/table/index.js +10 -8
- package/es/table/index.js.map +1 -0
- package/package.json +12 -13
- package/src/components/component-provider/components/index.vue +81 -0
- package/src/components/component-provider/constants/index.ts +165 -0
- package/src/components/component-provider/index.ts +6 -0
- package/src/components/component-provider/types/index.ts +90 -0
- package/src/components/form/components/BaseField/index.vue +188 -0
- package/src/components/form/components/BaseField/utils/index.ts +16 -0
- package/src/components/form/components/BaseFormItem/index.vue +163 -0
- package/src/components/form/components/ContainerFragment/index.vue +24 -0
- package/src/components/form/components/GroupedFieldAttrs/index.vue +118 -0
- package/src/components/form/components/PathProvider/index.vue +19 -0
- package/src/components/form/components/ProForm/index.vue +109 -0
- package/src/components/form/components/SlotComponent/index.vue +26 -0
- package/src/components/form/components/index.ts +15 -0
- package/src/components/form/constants/index.ts +135 -0
- package/src/components/form/hooks/index.ts +5 -0
- package/src/components/form/hooks/useFields.ts +67 -0
- package/src/components/form/hooks/useForm.ts +110 -0
- package/src/components/form/hooks/useFormRef.ts +35 -0
- package/src/components/form/index.ts +29 -0
- package/src/components/form/types/index.ts +271 -0
- package/src/components/table/components/ColumnControl.vue +132 -0
- package/src/components/table/components/DefaultSearchFormContainer.vue +20 -0
- package/src/components/table/components/DefaultTableContainer.vue +20 -0
- package/src/components/table/components/ProTable.vue +366 -0
- package/src/components/table/components/SearchForm.vue +295 -0
- package/src/components/table/components/SizeControl.vue +59 -0
- package/src/components/table/components/icons/ColumnHeightOutlined.vue +4 -0
- package/src/components/table/components/icons/DownOutlined.vue +4 -0
- package/src/components/table/components/icons/FilterOutlined.vue +4 -0
- package/src/components/table/components/index.ts +4 -0
- package/src/components/table/hooks/index.ts +1 -0
- package/src/components/table/hooks/useTable.ts +130 -0
- package/src/components/table/index.ts +14 -0
- package/src/components/table/types/index.ts +74 -0
- package/src/index.ts +80 -0
- package/src/shared/core/index.ts +37 -0
- package/src/shared/ui/index.ts +60 -0
- package/es/core/index-ghYuQ3Sy.js +0 -360
- package/es/vendor/utils/lodash-es-p6jau26B.js +0 -1120
package/AI-CONTEXT.md
CHANGED
|
@@ -1,123 +1,236 @@
|
|
|
1
|
-
# @qin-ui/antd-vue-pro
|
|
1
|
+
# @qin-ui/antd-vue-pro — AI Context
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Schema-driven component library wrapping **ant-design-vue v4** (`a-` prefix). Describe UIs as JS objects instead of template tag soup.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Architecture
|
|
8
|
+
|
|
9
|
+
### 1.1 Three-layer rendering
|
|
6
10
|
|
|
7
|
-
```bash
|
|
8
|
-
npm install @qin-ui/antd-vue-pro ant-design-vue vue
|
|
9
11
|
```
|
|
12
|
+
Field[] config layer { path:'name', component:'input', span:8, label:'Name', placeholder:'...' }
|
|
13
|
+
│
|
|
14
|
+
@qin-ui/antd-vue-pro Schema parser — strips props layer by layer
|
|
15
|
+
│
|
|
16
|
+
ant-design-vue v4 a-input / a-select / a-table / a-form-item / a-col ...
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
ProForm/ProTable are **rendering engines**, not a component library. All actual UI comes from ant-design-vue. Field props are peeled off and dispatched to different DOM layers.
|
|
20
|
+
|
|
21
|
+
### 1.2 Component resolution
|
|
22
|
+
|
|
23
|
+
`Field.component` string → `componentMap` → ant-design-vue component.
|
|
24
|
+
|
|
25
|
+
If not found in the built-in map, the string is resolved against `ProComponentProvider` injected components; a Vue component object is rendered directly (used by `'custom'` internally).
|
|
10
26
|
|
|
11
|
-
|
|
27
|
+
### 1.3 Built-in component map
|
|
12
28
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
29
|
+
| Field `component` | ant-design-vue component | Key pass-through props (verify against https://antdv.com) |
|
|
30
|
+
| :----------------- | :----------------------- | :------------------------------------------------------------------------------------- |
|
|
31
|
+
| `'input'` | Input | placeholder, maxlength, allowClear, addonBefore, addonAfter, prefix, suffix, showCount |
|
|
32
|
+
| `'textarea'` | TextArea | rows, maxlength, showCount, autoSize |
|
|
33
|
+
| `'input-password'` | InputPassword | placeholder, maxlength, visibilityToggle |
|
|
34
|
+
| `'input-search'` | InputSearch | placeholder, loading, onSearch |
|
|
35
|
+
| `'input-number'` | InputNumber | min, max, step, precision, formatter, parser |
|
|
36
|
+
| `'select'` | Select | **options**, mode, showSearch, filterOption, allowClear, loading |
|
|
37
|
+
| `'cascader'` | Cascader | **options**, fieldNames, showSearch, allowClear |
|
|
38
|
+
| `'date-picker'` | DatePicker | picker, format, showTime, disabledDate, valueFormat |
|
|
39
|
+
| `'range-picker'` | RangePicker | format, showTime, disabledDate, allowClear |
|
|
40
|
+
| `'time-picker'` | TimePicker | format, showSecond, hourStep, minuteStep |
|
|
41
|
+
| `'checkbox-group'` | CheckboxGroup | **options**, direction |
|
|
42
|
+
| `'radio-group'` | RadioGroup | **options**, direction, buttonStyle |
|
|
43
|
+
| `'switch'` | Switch | checkedChildren, unCheckedChildren, loading |
|
|
44
|
+
| `'slider'` | Slider | min, max, step, marks, range, tooltip |
|
|
45
|
+
| `'tree-select'` | TreeSelect | **treeData**, showSearch, treeCheckable, fieldNames |
|
|
46
|
+
| `'transfer'` | Transfer | **dataSource**, **titles**, **targetKeys**, showSearch, render |
|
|
47
|
+
| `'custom'` | (user-supplied) | component receives a Vue component or `h()` render function |
|
|
48
|
+
|
|
49
|
+
> The prop column is illustrative. **Always verify prop names/types against [antdv.com](https://antdv.com).**
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 2. Property layering (core rule)
|
|
54
|
+
|
|
55
|
+
Field props are **stripped in layers** and dispatched to different DOM targets.
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
<a-col :span="8"> ← Grid layer
|
|
59
|
+
<a-form-item label="City"> ← FormItem layer
|
|
60
|
+
<a-select placeholder="..." /> ← Input-control layer
|
|
61
|
+
</a-form-item>
|
|
62
|
+
</a-col>
|
|
16
63
|
```
|
|
17
64
|
|
|
18
|
-
|
|
65
|
+
### 2.1 Layer dispatch
|
|
19
66
|
|
|
20
|
-
|
|
67
|
+
**Grid layer → `<a-col>`** (only when grid is enabled):
|
|
68
|
+
`span`, `order`, `offset`, `push`, `pull`, `flex`, `xs`, `sm`, `md`, `lg`, `xl`, `xxl`
|
|
21
69
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
| `ProForm` | 配置驱动表单组件 |
|
|
25
|
-
| `ProTable` | 配置驱动表格组件 |
|
|
26
|
-
| `ProComponentProvider` | 全局配置提供者 |
|
|
70
|
+
**FormItem layer → `<a-form-item>`**:
|
|
71
|
+
`label`, `rules`, `colon`, `labelAlign`, `labelCol`, `wrapperCol`, `tooltip`, `extra`, `help`, `validateFirst`, `validateTrigger`, `valuePropName`, `normalize`, `formItemClass`→`class`, `formItemStyle`→`style`, `formItemContainer`, `formItemDataAttrs`→`data-*`
|
|
27
72
|
|
|
28
|
-
|
|
73
|
+
**Input-control layer → the input component** (everything else):
|
|
74
|
+
`disabled`, `placeholder`, `allowClear`, `options`, `showSearch`, `maxlength`, `mode`, `componentClass`→`class`, `componentStyle`→`style`, `componentDataAttrs`→`data-*`, and any ant-design-vue props for that component.
|
|
29
75
|
|
|
30
|
-
|
|
31
|
-
| ------------------ | ------------ |
|
|
32
|
-
| `useForm<D>()` | 创建表单实例 |
|
|
33
|
-
| `useFields<D>()` | 字段配置管理 |
|
|
34
|
-
| `useFormRef()` | 表单组件引用 |
|
|
35
|
-
| `useTable<D, T>()` | 创建表格实例 |
|
|
76
|
+
**Consumed by ProForm logic, not bound to DOM**: `component`, `fields`, `hidden`, `slots`, `modelProp`, `valueFormatter`, `componentContainer`, `extraProps`.
|
|
36
77
|
|
|
37
|
-
|
|
78
|
+
### 2.2 modelProp
|
|
38
79
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const form = useForm
|
|
55
|
-
{
|
|
56
|
-
|
|
80
|
+
Controls the `v-model:xxx` binding name.
|
|
81
|
+
|
|
82
|
+
- Default: `modelProp: 'value'` → `v-model:value`
|
|
83
|
+
- Switch uses `checked` — **ProComponentProvider presets `modelProp: 'checked'` for `'switch'`** so you rarely set it manually.
|
|
84
|
+
- Override per-field when using a custom component that expects a different v-model prop.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 3. Progressive usage
|
|
89
|
+
|
|
90
|
+
### Level 1: Config-driven (no hand-written a-\* tags)
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import { ProForm, useForm } from '@qin-ui/antd-vue-pro';
|
|
94
|
+
|
|
95
|
+
const form = useForm({ username: '', password: '' }, [
|
|
96
|
+
{
|
|
97
|
+
path: 'username',
|
|
98
|
+
component: 'input',
|
|
99
|
+
label: '用户名',
|
|
100
|
+
placeholder: '请输入',
|
|
101
|
+
rules: [{ required: true }],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
path: 'password',
|
|
105
|
+
component: 'input-password',
|
|
106
|
+
label: '密码',
|
|
107
|
+
placeholder: '请输入',
|
|
108
|
+
rules: [{ required: true }],
|
|
109
|
+
},
|
|
57
110
|
]);
|
|
58
|
-
</script>
|
|
59
111
|
```
|
|
60
112
|
|
|
61
|
-
|
|
113
|
+
```html
|
|
114
|
+
<ProForm :form="form" />
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Level 2: Field linkage
|
|
118
|
+
|
|
119
|
+
Control props (`disabled`, `hidden`, `rules`, etc.) support three reactivity patterns:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
// A) computed() — declarative, for linkages known at init (preferred)
|
|
123
|
+
disabled: computed(() => !form.formData.enabled),
|
|
124
|
+
rules: computed(() => [{ required: form.formData.hasLimit, message: '必填' }]),
|
|
125
|
+
|
|
126
|
+
// B) ref() — external shared state
|
|
127
|
+
const isDisabled = ref(false);
|
|
128
|
+
|
|
129
|
+
// C) setField() — imperative, for event-driven changes
|
|
130
|
+
form.setField('limitCount', { disabled: true });
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Rule: pick the simplest. computed() for init-time, setField() for runtime events, ref() for external state.**
|
|
134
|
+
|
|
135
|
+
### Level 3: Custom component
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { h } from 'vue';
|
|
139
|
+
import CustomInput from './CustomInput.vue';
|
|
140
|
+
|
|
141
|
+
// In field config:
|
|
142
|
+
{ path: 'key', component: (p, ctx) => h(CustomInput, { ...p, ...ctx.attrs }) }
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Or via scoped slot in template (all binding params forwarded via `v-bind="scoped"`):
|
|
146
|
+
|
|
147
|
+
```html
|
|
148
|
+
<ProForm :form="form">
|
|
149
|
+
<template #agreement="scoped">
|
|
150
|
+
<a-checkbox v-bind="scoped">同意协议</a-checkbox>
|
|
151
|
+
</template>
|
|
152
|
+
</ProForm>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 4. Anti-patterns
|
|
158
|
+
|
|
159
|
+
- **Never hand-write `<a-form-item>` inside `<ProForm>`.** ProForm renders FormItems from Field config automatically.
|
|
160
|
+
- **Never guess pass-through prop names.** Verify against [ant-design-vue docs](https://antdv.com).
|
|
161
|
+
- **Don't confuse Grid props with input props.** `span` goes to `<a-col>`, not the input.
|
|
162
|
+
- **Use `computed()` for reactive Field configs.** Plain values won't track dependencies.
|
|
163
|
+
- **Prefer the simplest linkage pattern.** Don't use `setField()` when `computed()` suffices.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## 5. ProComponentProvider — global defaults
|
|
168
|
+
|
|
169
|
+
Wrap your app to set defaults for all ProForm/ProTable instances. Merged with priority (highest first):
|
|
170
|
+
|
|
171
|
+
1. **Field-level config** (always wins)
|
|
172
|
+
2. **`componentVars`** passed to ProComponentProvider
|
|
173
|
+
3. **`INJECT_CONFIG`** built-in presets
|
|
174
|
+
|
|
175
|
+
### Built-in presets (INJECT_CONFIG)
|
|
176
|
+
|
|
177
|
+
| Component | Preset |
|
|
178
|
+
| :--------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------- |
|
|
179
|
+
| `switch` | `{ modelProp: 'checked' }` |
|
|
180
|
+
| `input` | `{ maxlength: 100, allowClear: true, placeholder: '请输入' }` |
|
|
181
|
+
| `textarea` | `{ maxlength: 200, autoSize: {minRows:3,maxRows:6}, showCount: true, allowClear: true, placeholder: '请输入' }` |
|
|
182
|
+
| `select` / `cascader` | `{ allowClear: true, placeholder: '请选择', getPopupContainer }` |
|
|
183
|
+
| `input-number` | `{ max: 10^15, min: -(10^15), controls: false, placeholder: '请输入', style: {width:'100%'} }` |
|
|
184
|
+
| `date-picker` / `range-picker` / `time-picker` | `{ allowClear: true, getPopupContainer, style: {width:'100%'} }` |
|
|
185
|
+
| `pro-table` | `{ pagination: {showTotal, showSizeChanger, showQuickJumper}, searchFormConfig: {layout:'grid'}, control: true, addIndexColumn: true }` |
|
|
186
|
+
| `pro-form` | `{ grid: { gutter: {xs:8, sm:16, md:16, lg:24} } }` |
|
|
187
|
+
| `pro-form-item` | `{ validateFirst: true, span: 8 }` |
|
|
188
|
+
|
|
189
|
+
### Override example
|
|
62
190
|
|
|
63
191
|
```vue
|
|
64
|
-
<
|
|
192
|
+
<ProComponentProvider
|
|
193
|
+
:component-vars="{
|
|
194
|
+
'pro-form-item': { span: 6 },
|
|
195
|
+
input: { maxlength: 200 },
|
|
196
|
+
select: { showSearch: true },
|
|
197
|
+
'pro-table': { addIndexColumn: false },
|
|
198
|
+
}"
|
|
199
|
+
>
|
|
200
|
+
<ProForm :form="form" />
|
|
65
201
|
<ProTable :table="table" />
|
|
66
|
-
</
|
|
202
|
+
</ProComponentProvider>
|
|
203
|
+
```
|
|
67
204
|
|
|
68
|
-
|
|
69
|
-
interface User {
|
|
70
|
-
name: string;
|
|
71
|
-
age: number;
|
|
72
|
-
}
|
|
205
|
+
---
|
|
73
206
|
|
|
74
|
-
|
|
207
|
+
## 6. ProTable quick reference
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
import { ProTable, useTable } from '@qin-ui/antd-vue-pro';
|
|
211
|
+
|
|
212
|
+
const table = useTable<Row>({
|
|
75
213
|
columns: [
|
|
76
|
-
{
|
|
77
|
-
{
|
|
214
|
+
{ title: 'ID', dataIndex: 'id', width: 80 },
|
|
215
|
+
{ title: 'Name', dataIndex: 'name', width: 120 },
|
|
216
|
+
],
|
|
217
|
+
// searchFields uses the same Field[] format as ProForm
|
|
218
|
+
searchFields: [
|
|
219
|
+
{ path: 'name', component: 'input', placeholder: 'Search' },
|
|
220
|
+
{ path: 'status', component: 'select', options: [...] },
|
|
78
221
|
],
|
|
79
|
-
dataSource: [],
|
|
80
222
|
});
|
|
81
|
-
|
|
223
|
+
// table.searchForm is a ProForm instance — all form methods available
|
|
82
224
|
```
|
|
83
225
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
每个字段支持以下属性:
|
|
87
|
-
|
|
88
|
-
- `path` - 数据路径(类型安全)
|
|
89
|
-
- `label` - 字段标签
|
|
90
|
-
- `component` - 组件名(内置支持: input, textarea, input-search, input-password, input-number, select, cascader, date-picker, range-picker, time-picker, checkbox-group, radio-group, switch, slider, tree-select, transfer, custom)
|
|
91
|
-
- `hidden` - 是否隐藏
|
|
92
|
-
- `disabled` - 是否禁用
|
|
93
|
-
- `rules` - 校验规则
|
|
94
|
-
- `valueFormatter` - 值格式化函数
|
|
95
|
-
- `fields` - 嵌套子字段
|
|
96
|
-
- `grid` - 网格布局
|
|
97
|
-
- `slots` - FormItem 插槽配置
|
|
98
|
-
- `componentStyle/componentClass` - 组件样式
|
|
99
|
-
- `componentContainer` - 组件容器包装
|
|
100
|
-
- `formItemStyle/formItemClass` - FormItem 样式
|
|
101
|
-
- `formItemContainer` - FormItem 容器包装
|
|
102
|
-
- `modelProp` - v-model 绑定属性名
|
|
103
|
-
|
|
104
|
-
完整类型定义见 `Field<ComponentName, D>`。
|
|
105
|
-
|
|
106
|
-
## 表格列配置(Column)
|
|
107
|
-
|
|
108
|
-
每列支持以下属性:
|
|
109
|
-
|
|
110
|
-
- `dataIndex` - 数据路径(优先使用)
|
|
111
|
-
- `key` - 列标识(dataIndex 不满足时使用)
|
|
112
|
-
- `hidden` - 是否隐藏
|
|
113
|
-
- 所有 ant-design-vue ColumnType 属性(title, width, fixed, align 等)
|
|
114
|
-
|
|
115
|
-
## 类型扩展
|
|
116
|
-
|
|
117
|
-
```typescript
|
|
118
|
-
declare module '@qin-ui/antd-vue-pro' {
|
|
119
|
-
interface ComponentMap {
|
|
120
|
-
'my-custom-component': typeof MyComponent;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
226
|
+
```html
|
|
227
|
+
<ProTable :table="table" :search="fetchData" addIndexColumn immediateSearch />
|
|
123
228
|
```
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## 7. References
|
|
233
|
+
|
|
234
|
+
1. **`node_modules/@qin-ui/antd-vue-pro/api.json`** — Structured API metadata (signatures, types, JSDoc examples)
|
|
235
|
+
2. **`node_modules/@qin-ui/antd-vue-pro/README.md`** — Full usage docs and code examples
|
|
236
|
+
3. **[antdv.com](https://antdv.com)** — ant-design-vue component API reference (always check before writing pass-through props)
|
package/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023-present pro-components
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/api.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-
|
|
2
|
+
"generatedAt": "2026-07-09T04:30:45.412Z",
|
|
3
3
|
"name": "@qin-ui/antd-vue-pro",
|
|
4
4
|
"api": [
|
|
5
5
|
{
|
|
@@ -19,12 +19,19 @@
|
|
|
19
19
|
"signature": "export type ComponentVars = Partial<RequiredComponentVars>;",
|
|
20
20
|
"description": "组件全局配置\nRequiredComponentVars 的 Partial 版本,用于 ProComponentProvider 的 props"
|
|
21
21
|
},
|
|
22
|
+
{
|
|
23
|
+
"name": "ContainerFragment",
|
|
24
|
+
"type": "component",
|
|
25
|
+
"package": "@qin-ui/antd-vue-pro",
|
|
26
|
+
"signature": "<ContainerFragment>",
|
|
27
|
+
"description": "容器分片渲染组件。用于动态渲染表单行或表单项的外部包裹容器(例如 Grid 行、Col 列等布局容器)。"
|
|
28
|
+
},
|
|
22
29
|
{
|
|
23
30
|
"name": "ProForm",
|
|
24
31
|
"type": "component",
|
|
25
32
|
"package": "@qin-ui/antd-vue-pro",
|
|
26
33
|
"signature": "<ProForm>",
|
|
27
|
-
"description": "@qin-ui/antd-vue-pro 配置驱动表单组件\n通过配置驱动的方式快速构建表单,支持:\n- 字段联动(通过 setField、watch 等实现)\n- 嵌套字段(通过 fields 递归配置)\n- 自定义组件(通过 component 属性和 custom 类型)\n- 网格布局(通过 grid 属性)\n- 动态插槽(以字段 path 命名的插槽)\n- 全局配置注入(通过 ProComponentProvider)",
|
|
34
|
+
"description": "@qin-ui/antd-vue-pro 配置驱动表单组件\n架构设计说明 (Architecture Overview)\n[ 数据层 (Core) ] => [ 绑定层 (ProForm) ] => [ 渲染层 (BaseFormItem / BaseField) ]\n1. 数据隔离:ProForm 本身不负责存储和管理表单状态,所有核心状态(formData, fields, 校验规则)\n均交由底层的 `useForm`(@qin-ui/pro-components-core)驱动。\n2. 上下文透传:通过 `provide` 将核心状态下发给子组件,避免了深层嵌套的 Props 传递。\n3. 递归渲染:网格布局和具体字段的解析交由 `<BaseFormItem>` 递归完成,实现了 UI 布局与表单逻辑的解耦。\n通过配置驱动的方式快速构建表单,支持:\n- 字段联动(通过 setField、watch 等实现)\n- 嵌套字段(通过 fields 递归配置)\n- 自定义组件(通过 component 属性和 custom 类型)\n- 网格布局(通过 grid 属性)\n- 动态插槽(以字段 path 命名的插槽)\n- 全局配置注入(通过 ProComponentProvider)",
|
|
28
35
|
"typeParams": [
|
|
29
36
|
{
|
|
30
37
|
"name": "F"
|
|
@@ -34,13 +41,6 @@
|
|
|
34
41
|
"```vue\n<template>\n<ProForm :form=\"form\" :fields=\"fields\" @submit=\"handleSubmit\">\n<template #name=\"{ value, disabled }\">\n<a-input :value=\"value\" :disabled=\"disabled\" />\n</template>\n</ProForm>\n</template>\n```"
|
|
35
42
|
]
|
|
36
43
|
},
|
|
37
|
-
{
|
|
38
|
-
"name": "ContainerFragment",
|
|
39
|
-
"type": "component",
|
|
40
|
-
"package": "@qin-ui/antd-vue-pro",
|
|
41
|
-
"signature": "<ContainerFragment>",
|
|
42
|
-
"description": "容器分片渲染组件。用于动态渲染表单行或表单项的外部包裹容器(例如 Grid 行、Col 列等布局容器)。"
|
|
43
|
-
},
|
|
44
44
|
{
|
|
45
45
|
"name": "SlotComponent",
|
|
46
46
|
"type": "component",
|
|
@@ -72,9 +72,9 @@
|
|
|
72
72
|
"name": "useFormData",
|
|
73
73
|
"type": "function",
|
|
74
74
|
"package": "@qin-ui/antd-vue-pro",
|
|
75
|
-
"signature": "export const useFormData = <D extends Data = Data>(\n initFormData?: ExtendWithAny<DeepPartial<D>>\n) =>",
|
|
75
|
+
"signature": "export const useFormData = <D extends Data = Data>(\n initFormData?: ExtendWithAny<DeepPartial<D>>\n): UseFormDataReturn<D> =>",
|
|
76
76
|
"description": "表单数据处理 Hook\n提供响应式表单数据的管理能力,支持:\n- 响应式数据存储(基于 Vue reactive)\n- 深层路径读写(支持点号分隔,如 'address.city')\n- 类型安全的路径提示(传入泛型 D 后,path 参数可获得类型推导)\n- 父子表单自动注入(非根表单会从注入中获取数据)",
|
|
77
|
-
"returns": "{
|
|
77
|
+
"returns": "{UseFormDataReturn<D>} 表单数据操作对象",
|
|
78
78
|
"typeParams": [
|
|
79
79
|
{
|
|
80
80
|
"name": "D"
|
|
@@ -88,15 +88,16 @@
|
|
|
88
88
|
"name": "useFields",
|
|
89
89
|
"type": "function",
|
|
90
90
|
"package": "@qin-ui/antd-vue-pro",
|
|
91
|
-
"signature": "export
|
|
92
|
-
"description": "
|
|
91
|
+
"signature": "export function useFields<D extends Data = Data>(\n initFields?: Fields<D>\n): UseFieldsReturn<D, Field<ComponentName, D>, FormItemInstance>;",
|
|
92
|
+
"description": "字段配置管理 Hook\n基于 `@qin-ui/pro-components-core` 的 `useFields`,将泛型参数绑定为 Ant Design Vue 的本地类型:\n- 字段类型 F -> `Field<ComponentName, D>`(支持 Ant Design Vue 组件类型推导)\n- FormItem 实例 -> Ant Design Vue 的 `FormItemInstance`\n提供对字段配置数组的增删改查操作,支持:\n- 通过路径字符串或查找函数定位字段\n- 深层嵌套字段的遍历和匹配\n- 字段配置的合并/覆盖更新\n- 字段的添加、插入、删除\n- 父级字段查找\n- `fields` - 字段配置数组(响应式 Ref\\<F[]\\>)\n- `getField(path)` - 获取字段配置,支持路径字符串或查找函数\n- `setField(path, field, options?)` - 更新字段配置,默认合并模式\n- `deleteField(path, options?)` - 删除字段配置\n- `appendField(path, field, options?)` - 在指定字段后追加\n- `prependField(path, field, options?)` - 在指定字段前插入\n- `getParentField(path, options?)` - 获取父级字段配置",
|
|
93
|
+
"returns": "字段操作对象,包含以下属性:",
|
|
93
94
|
"typeParams": [
|
|
94
95
|
{
|
|
95
96
|
"name": "D"
|
|
96
97
|
}
|
|
97
98
|
],
|
|
98
99
|
"examples": [
|
|
99
|
-
"```ts\ninterface User { name: string; age: number }\n\nconst { fields, getField, setField } = useFields<User>([\n{ path: 'name', label: '姓名', component: 'input' },\n{ path: 'age', label: '年龄', component: 'input-number' },\n])\n\n//
|
|
100
|
+
"```ts\ninterface User { name: string; age: number }\n\nconst { fields, getField, setField } = useFields<User>([\n{ path: 'name', label: '姓名', component: 'input' },\n{ path: 'age', label: '年龄', component: 'input-number' },\n])\n\n// 通过路径获取\ngetField('name')\n// 通过查找函数获取\ngetField(f => f.label === '姓名')\n// 更新字段(合并模式)\nsetField('name', { label: '用户名', disabled: true })\n```"
|
|
100
101
|
]
|
|
101
102
|
},
|
|
102
103
|
{
|
|
@@ -104,14 +105,14 @@
|
|
|
104
105
|
"type": "type",
|
|
105
106
|
"package": "@qin-ui/antd-vue-pro",
|
|
106
107
|
"signature": "export type UseFields<D extends Data = Data> = ReturnType<typeof useFields<D>>;",
|
|
107
|
-
"description": "useFields
|
|
108
|
+
"description": "useFields 返回值类型"
|
|
108
109
|
},
|
|
109
110
|
{
|
|
110
111
|
"name": "Form",
|
|
111
112
|
"type": "type",
|
|
112
113
|
"package": "@qin-ui/antd-vue-pro",
|
|
113
114
|
"signature": "export type Form<\n D extends Data = Data,\n F extends Field<ComponentName, D> = Field<ComponentName, D>,\n> = _Form<D, F, FormInstance>;",
|
|
114
|
-
"description": "在 core Form
|
|
115
|
+
"description": "表单实例类型\n在 core Form 类型的基础上,将字段类型 F 绑定为本地 Field<ComponentName, D>,\n将底层表单实例 I 绑定为 Ant Design Vue 的 FormInstance,使 formRef 获得完整的类型提示。\n1. `setFormData(path, value)` - 设置指定路径的值<br>\n2. `setFormData(path, prev => newVal)` - 函数式更新<br>\n3. `setFormData({ ... })` - 批量覆盖整个表单",
|
|
115
116
|
"typeParams": [
|
|
116
117
|
{
|
|
117
118
|
"name": "D"
|
|
@@ -121,33 +122,34 @@
|
|
|
121
122
|
}
|
|
122
123
|
],
|
|
123
124
|
"examples": [
|
|
124
|
-
"```ts\ninterface User { name: string; age: number }\nconst form: Form<User> = useForm({ name: '张三', age: 25 })\nform.formRef.value?.validate()
|
|
125
|
+
"```ts\ninterface User { name: string; age: number }\nconst form: Form<User> = useForm({ name: '张三', age: 25 })\n\nform.formData.name // 直接读写响应式数据\nform.getFormData('name') // 通过路径读取\nform.setFormData('name', '李四') // 更新数据\nform.formRef.value?.validate() // 访问底层 Form 实例\n```"
|
|
125
126
|
]
|
|
126
127
|
},
|
|
127
128
|
{
|
|
128
129
|
"name": "useForm",
|
|
129
130
|
"type": "function",
|
|
130
131
|
"package": "@qin-ui/antd-vue-pro",
|
|
131
|
-
"signature": "export
|
|
132
|
-
"description": "
|
|
132
|
+
"signature": "export function useForm<D extends Data = Data>(\n initFormData?: ExtendWithAny<DeepPartial<D>>,\n initFields?: Field<ComponentName, D>[],\n root?: boolean\n): Form<D, Field<ComponentName, D>>;",
|
|
133
|
+
"description": "创建表单实例的 Hook\n基于 `@qin-ui/pro-components-core` 的 `useForm`,将泛型参数绑定为 Ant Design Vue 的本地类型:\n- 字段类型 F -> `Field<ComponentName, D>`(支持 Ant Design Vue 所有内置组件类型推导)\n- 表单实例 -> Ant Design Vue 的 `FormInstance`(使 formRef 获得完整的类型提示)\n表单实例组合了三个子模块的能力:\n- **useFormData**:表单数据管理(响应式数据、读写、批量更新)\n- **useFields**:字段配置管理(增删改查字段配置,支持嵌套)\n- **useFormRef**:底层 Form 组件实例引用",
|
|
134
|
+
"returns": "{Form<D>} 表单实例,包含数据操作、字段操作和 ref 操作",
|
|
133
135
|
"typeParams": [
|
|
134
136
|
{
|
|
135
137
|
"name": "D"
|
|
136
138
|
}
|
|
137
139
|
],
|
|
138
140
|
"examples": [
|
|
139
|
-
"```ts\ninterface User { name: string; age: number }\n\nconst form = useForm<User>(\n{ name: '张三', age: 25 },\n[\n{ path: 'name', label: '姓名', component: 'input' },\n{ path: 'age', label: '年龄', component: 'input-number' },\n],\ntrue\n)\n\n//
|
|
141
|
+
"```ts\ninterface User { name: string; age: number }\n\n// 方式一:同时传入初始数据和字段\nconst form = useForm<User>(\n{ name: '张三', age: 25 },\n[\n{ path: 'name', label: '姓名', component: 'input' },\n{ path: 'age', label: '年龄', component: 'input-number' },\n],\ntrue\n)\n\n// 方式二:仅设置 root 标识\nconst form = useForm<User>(true)\n\n// 使用\nconst { formData, formRef, fields, setFormData, getField } = form\nsetFormData('name', '李四')\nawait formRef.value?.validate()\n```"
|
|
140
142
|
]
|
|
141
143
|
},
|
|
142
144
|
{
|
|
143
145
|
"name": "useFormRef",
|
|
144
146
|
"type": "function",
|
|
145
147
|
"package": "@qin-ui/antd-vue-pro",
|
|
146
|
-
"signature": "export
|
|
147
|
-
"description": "
|
|
148
|
-
"returns": "
|
|
148
|
+
"signature": "export function useFormRef(): UseFormRefReturn<FormInstance>",
|
|
149
|
+
"description": "表单组件实例引用 Hook\n基于 `@qin-ui/pro-components-core` 的 `useFormRef`,将泛型参数绑定为 Ant Design Vue 的 `FormInstance`,\n使 formRef 获取到完整的 Ant Design Vue Form 组件 API 类型提示(如 `validate()`、`resetFields()` 等)。\n`formRef` 由 ProForm 组件内部自动通过 `setFormRef` 绑定,无需手动调用。\n- `formRef` — Ant Design Vue Form 组件实例的响应式引用(`Ref<FormInstance | undefined>`)\n- `setFormRef(inst)` — 设置 Form 组件实例,由 ProForm 内部自动调用",
|
|
150
|
+
"returns": "表单组件实例引用管理对象:",
|
|
149
151
|
"examples": [
|
|
150
|
-
"```ts\nconst { formRef, setFormRef } = useFormRef()\n
|
|
152
|
+
"```ts\nconst { formRef, setFormRef } = useFormRef()\n\n// formRef 由 ProForm 自动绑定,可直接使用\nawait formRef.value?.validate()\nformRef.value?.resetFields()\nformRef.value?.scrollToField('username')\n```"
|
|
151
153
|
]
|
|
152
154
|
},
|
|
153
155
|
{
|
|
@@ -179,7 +181,7 @@
|
|
|
179
181
|
"type": "type",
|
|
180
182
|
"package": "@qin-ui/antd-vue-pro",
|
|
181
183
|
"signature": "export type Table<\n D extends Data = Data,\n T extends Data = ExtendWithAny<D>,\n> = _Table<D, T, Column<T>>;",
|
|
182
|
-
"description": "在 core Table 类型的基础上,将列类型 C 绑定为本地 Column<T>,\n使 columns 操作获得 Ant Design Vue
|
|
184
|
+
"description": "表格实例类型\n在 core Table 类型的基础上,将列类型 C 绑定为本地 Column<T>,\n使 columns 操作获得 Ant Design Vue 表格列的完整属性类型提示。",
|
|
183
185
|
"typeParams": [
|
|
184
186
|
{
|
|
185
187
|
"name": "D"
|
|
@@ -189,15 +191,24 @@
|
|
|
189
191
|
}
|
|
190
192
|
],
|
|
191
193
|
"examples": [
|
|
192
|
-
"```ts\ninterface SearchParams { keyword: string }\ninterface User { name: string; age: number }\n\nconst table: Table<SearchParams, User> = useTable({
|
|
194
|
+
"```ts\ninterface SearchParams { keyword: string }\ninterface User { name: string; age: number }\n\nconst table: Table<SearchParams, User> = useTable({\ncolumns: [{ dataIndex: 'name', title: '姓名' }],\n})\n\ntable.columns.value // 访问列配置\ntable.setColumn('name', { width: 150 }) // 更新列\ntable.setPageParam({ current: 2 }) // 切换页码\ntable.searchForm.setFormData('keyword', '搜索词') // 操作搜索表单\n```"
|
|
193
195
|
]
|
|
194
196
|
},
|
|
195
197
|
{
|
|
196
198
|
"name": "useTable",
|
|
197
199
|
"type": "function",
|
|
198
200
|
"package": "@qin-ui/antd-vue-pro",
|
|
199
|
-
"signature": "export
|
|
200
|
-
"description": "
|
|
201
|
+
"signature": "export function useTable<\n D extends Data = Data,\n T extends Data = ExtendWithAny<D>,\n>(params:",
|
|
202
|
+
"description": "创建表格实例的 Hook\n基于 `@qin-ui/pro-components-core` 的 `useTable`,将列类型绑定为本地 `Column<T>`。\n是 ProTable 组件的核心 Hook,提供了:\n- 列配置管理(增删改查)\n- 数据源管理\n- 分页管理\n- 搜索表单集成(内部使用 useForm)\n- 查询参数重置",
|
|
203
|
+
"params": [
|
|
204
|
+
{
|
|
205
|
+
"name": "params",
|
|
206
|
+
"type": "object",
|
|
207
|
+
"optional": false,
|
|
208
|
+
"description": "表格配置参数"
|
|
209
|
+
}
|
|
210
|
+
],
|
|
211
|
+
"returns": "{Table<D, T>} 表格实例",
|
|
201
212
|
"typeParams": [
|
|
202
213
|
{
|
|
203
214
|
"name": "D"
|
|
@@ -207,7 +218,7 @@
|
|
|
207
218
|
}
|
|
208
219
|
],
|
|
209
220
|
"examples": [
|
|
210
|
-
"```ts\ninterface SearchParams { keyword: string }\ninterface User { name: string; age: number; email: string }\n\nconst table = useTable<SearchParams, User>({\ncolumns: [\n{
|
|
221
|
+
"```ts\ninterface SearchParams { keyword: string; status: string }\ninterface User { name: string; age: number; email: string }\n\nconst table = useTable<SearchParams, User>({\ncolumns: [\n{ dataIndex: 'name', title: '姓名', width: 120 },\n{ dataIndex: 'age', title: '年龄', width: 80 },\n],\ndataSource: [],\npageParam: { current: 1, pageSize: 20, total: 0 },\nsearchParam: { keyword: '', status: '' },\nsearchFields: [\n{ path: 'keyword', label: '关键词', component: 'input' },\n{ path: 'status', label: '状态', component: 'select' },\n],\n})\n\n// 查询\nconst handleSearch = async () => {\nconst res = await fetchUserList({\n...table.searchForm.formData,\n...table.pageParam,\n})\ntable.dataSource.value = res.data\ntable.setPageParam({ total: res.total })\n}\n\n// 重置\nconst handleReset = () => {\ntable.resetQueryParams()\nhandleSearch()\n}\n```"
|
|
211
222
|
]
|
|
212
223
|
},
|
|
213
224
|
{
|