@qin-ui/element-plus-pro 1.1.3 → 1.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 +86 -249
- package/README.md +36 -28
- package/api.json +7 -1
- package/bin/init-ai.mjs +132 -40
- package/es/components/component-provider/components/index.vue.d.ts +6 -0
- package/es/components/component-provider/components/index.vue.d.ts.map +1 -1
- package/es/components/component-provider/constants/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 +3 -1
- package/es/components/form/components/BaseField/utils/index.d.ts.map +1 -1
- package/es/components/table/components/ColumnControl.vue.d.ts +2 -1
- package/es/components/table/components/ColumnControl.vue.d.ts.map +1 -1
- package/es/components/table/components/ProTable.vue.d.ts +3 -2
- package/es/components/table/components/ProTable.vue.d.ts.map +1 -1
- package/es/components/table/components/SearchForm.vue.d.ts.map +1 -1
- package/es/components/table/components/SizeControl.vue.d.ts.map +1 -1
- package/es/components/table/types/index.d.ts +22 -0
- package/es/components/table/types/index.d.ts.map +1 -1
- package/es/components/table/useTable.d.ts.map +1 -1
- package/es/element-plus-pro.css +13 -13
- package/es/index.d.ts +1 -0
- package/es/index.d.ts.map +1 -1
- package/es/index.js +285 -125
- package/es/index.js.map +1 -1
- package/es/locale/en-US.d.ts +26 -0
- package/es/locale/en-US.d.ts.map +1 -0
- package/es/locale/index.d.ts +31 -0
- package/es/locale/index.d.ts.map +1 -0
- package/es/locale/zh-CN.d.ts +26 -0
- package/es/locale/zh-CN.d.ts.map +1 -0
- package/es/locale/zh-TW.d.ts +26 -0
- package/es/locale/zh-TW.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/components/component-provider/components/index.vue +14 -1
- package/src/components/component-provider/constants/index.ts +20 -39
- package/src/components/form/components/BaseField/index.vue +10 -4
- package/src/components/form/components/BaseField/utils/index.ts +66 -3
- package/src/components/table/components/ColumnControl.vue +83 -20
- package/src/components/table/components/ProTable.vue +36 -10
- package/src/components/table/components/SearchForm.vue +6 -3
- package/src/components/table/components/SizeControl.vue +9 -5
- package/src/components/table/types/index.ts +23 -0
- package/src/components/table/useTable.ts +13 -1
- package/src/index.ts +1 -0
- package/src/locale/en-US.ts +21 -0
- package/src/locale/index.ts +68 -0
- package/src/locale/zh-CN.ts +21 -0
- package/src/locale/zh-TW.ts +21 -0
package/AI-CONTEXT.md
CHANGED
|
@@ -3,19 +3,18 @@
|
|
|
3
3
|
基于 element-plus v2.x(`el-` 前缀)封装的 Schema 驱动组件库。
|
|
4
4
|
用 JS 配置对象描述 UI,不写 `<el-*>` 模板堆叠。ProForm/ProTable 是渲染引擎,所有真实 UI 来自 element-plus。
|
|
5
5
|
|
|
6
|
-
##
|
|
6
|
+
## 安装与使用
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
9
|
pnpm add @qin-ui/element-plus-pro # peerDeps: element-plus ^2.13.6, vue ^3.5
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
```ts
|
|
13
|
-
|
|
14
|
-
import '@qin-ui/element-plus-pro
|
|
15
|
-
app.use(ElementPlusPro); // 全局注册 ProForm / ProTable / ProComponentProvider
|
|
13
|
+
// 按需引入(推荐)
|
|
14
|
+
import { ProForm, ProTable, useForm, useTable } from '@qin-ui/element-plus-pro';
|
|
16
15
|
```
|
|
17
16
|
|
|
18
|
-
##
|
|
17
|
+
## 核心心智模型
|
|
19
18
|
|
|
20
19
|
**1. 配置驱动**:`useForm(数据, Field[])` / `useTable({ columns, searchFields })` 生成实例,组件接收实例。
|
|
21
20
|
|
|
@@ -31,7 +30,9 @@ app.use(ElementPlusPro); // 全局注册 ProForm / ProTable / ProComponentProvid
|
|
|
31
30
|
> 规则:`span` 给 Grid,`label`/`rules` 给 FormItem,其余给输入控件。
|
|
32
31
|
> **element-plus 命名约定**:用 `clearable`(不是 `allowClear`)、`showWordLimit`(不是 `showCount`)、`autosize`(小写 d);el-form-item 插槽为 `label` 和 `error`。
|
|
33
32
|
|
|
34
|
-
##
|
|
33
|
+
## 速查
|
|
34
|
+
|
|
35
|
+
### component 映射(Field.component 字符串 -> element-plus 组件)
|
|
35
36
|
|
|
36
37
|
`input`->el-input · `input-number`->el-input-number · `autocomplete`->el-autocomplete · `select`->el-select ·
|
|
37
38
|
`cascader`->el-cascader · `date-picker`->el-date-picker · `time-picker`->el-time-picker · `time-select`->el-time-select ·
|
|
@@ -42,292 +43,124 @@ app.use(ElementPlusPro); // 全局注册 ProForm / ProTable / ProComponentProvid
|
|
|
42
43
|
> `date-picker` 通过 `type` 子类型区分:`date`/`dates`/`daterange`/`datetime`/`datetimerange`/`week`/`month`/`monthrange`/`months`/`year`/`yearrange`/`years`。
|
|
43
44
|
> 写 Field 中输入控件的具体属性前,**属性名/类型以 https://element-plus.org 官方文档为准**。
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
### 隐式默认行为(INJECT_CONFIG,易踩坑)
|
|
46
47
|
|
|
47
48
|
由 `ProComponentProvider` 注入,优先级低于 Field 配置。**不写也有这些默认值,需知晓以免行为与预期不符:**
|
|
48
49
|
|
|
49
|
-
| component
|
|
50
|
-
|
|
|
51
|
-
| `switch`
|
|
52
|
-
| `input`
|
|
53
|
-
| `input.textarea`
|
|
54
|
-
| `input.password`
|
|
55
|
-
| `input-number`
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `pro-form
|
|
60
|
-
| `pro-
|
|
50
|
+
| component | 默认预设 |
|
|
51
|
+
| :-------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| `switch` | `{ modelProp: 'modelValue' }` -> v-model 绑 `modelValue`(element-plus 惯例,即 `v-model`) |
|
|
53
|
+
| `input` | `{ maxlength: 100, clearable: true }` |
|
|
54
|
+
| `input.textarea` | `{ maxlength: 200, autosize: {minRows:3,maxRows:6}, showWordLimit: true, clearable: true }` |
|
|
55
|
+
| `input.password` | `{ showPassword: true, maxlength: 100, clearable: true }` |
|
|
56
|
+
| `input-number` | `{ max: 1e15-1, min: -(1e15+1), controls: false, style:{width:'100%'} }` |
|
|
57
|
+
| `autocomplete` | `{ clearable: true }` |
|
|
58
|
+
| `select` / `cascader` / `tree-select` | `{ clearable: true }` |
|
|
59
|
+
| `date-picker` / `time-picker` / `time-select` | `{ style:{width:'100%'} }` |
|
|
60
|
+
| `pro-form` | `{ grid: { gutter: 24 } }` |
|
|
61
|
+
| `pro-form-item` | `{ span: 8 }` |
|
|
62
|
+
| `pro-table` | `{ pagination:{layout:'total, sizes, prev, pager, next, jumper', pageSizes:[10,20,30,40,50,100], background:true}, searchFormConfig:{layout:'grid', expand:{minExpandRows:2, expandStatus:false}}, control:true, addIndexColumn:true }` |
|
|
61
63
|
|
|
62
64
|
> `modelProp` 控制 v-model 绑定名,element-plus 默认 `'modelValue'`(即 `v-model`)。
|
|
63
|
-
> `date-picker` 支持按 type 子类型分别预设:`date-picker.date` / `.daterange` / `.datetime` / `.week` / `.month` / `.monthrange` / `.year` / `.yearrange`
|
|
65
|
+
> `date-picker` 支持按 type 子类型分别预设:`date-picker.date` / `.dates` / `.daterange` / `.datetime` / `.datetimerange` / `.week` / `.month` / `.monthrange` / `.months` / `.year` / `.yearrange` / `.years`,范围类型自动生成 `startPlaceholder`/`endPlaceholder`。
|
|
66
|
+
> `checkbox-group` / `radio-group` / `slider` / `transfer` 无预设(`{}`)。
|
|
67
|
+
> **占位符由 locale 兜底**:未显式设置 `placeholder` 时按组件类型自动生成(input 类 -> `input.placeholder`,select/cascader/tree-select 类 -> `select.placeholder`,日期/时间类 -> `date-picker.placeholder`,范围类型 -> `date-picker.start`/`date-picker.end` 等),语言随宿主组件库自动切换。
|
|
64
68
|
|
|
65
|
-
|
|
69
|
+
### 内置文案(locale)
|
|
66
70
|
|
|
67
|
-
|
|
68
|
-
// 重载一(常用):初始数据 + 字段配置
|
|
69
|
-
const form = useForm<User>(
|
|
70
|
-
{ name: '张三', age: 25 }, // initFormData
|
|
71
|
-
[
|
|
72
|
-
{
|
|
73
|
-
path: 'name',
|
|
74
|
-
label: '姓名',
|
|
75
|
-
component: 'input',
|
|
76
|
-
rules: [{ required: true }],
|
|
77
|
-
},
|
|
78
|
-
] // Field[]
|
|
79
|
-
);
|
|
80
|
-
// 重载二:仅拿实例(root=true/false)
|
|
81
|
-
const form = useForm<User>(true);
|
|
82
|
-
```
|
|
71
|
+
内置文案(查询/重置/收起/展开/序号/分页总数/占位符等)走 locale 体系,默认跟随宿主 element-plus 语言自动切换:
|
|
83
72
|
|
|
84
|
-
返回 `
|
|
73
|
+
- `useLocale()` 返回 `{ t, lang }`:`t(key, params?)` 翻译函数(支持 `{placeholder}` 参数)、`lang` 当前语言(`'zh-CN'` / `'zh-TW'` / `'en-US'`)
|
|
74
|
+
- 包导出 `zhCN` / `zhTW` / `enUS` 三套语言包(类型 `ProLocale`)
|
|
75
|
+
- `ProComponentProvider` 的 `locale` prop 可覆盖任意内置文案(如 `{ 'table.query': '搜索' }`),未覆盖的默认跟随宿主语言
|
|
85
76
|
|
|
86
|
-
|
|
87
|
-
| :------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------- |
|
|
88
|
-
| `form.formData` | 响应式数据,可直接读写,支持深层路径 `formData.address.city` |
|
|
89
|
-
| `form.getFormData(path)` / `form.setFormData(path, value)` | 路径读写;setFormData 还支持 `setFormData(path, prev=>new)` 和 `setFormData({...})` 批量覆盖 |
|
|
90
|
-
| `form.fields` | 字段配置数组(Ref) |
|
|
91
|
-
| `form.getField(path)` / `form.setField(path, patch)` | 字段增改查;setField 默认合并,`{updateType:'rewrite'}` 覆盖 |
|
|
92
|
-
| `form.deleteField` / `form.appendField` / `form.prependField` / `form.getParentField` | 字段增删 |
|
|
93
|
-
| `form.formRef` | 底层 element-plus Form 实例引用(Ref),`formRef.value?.validate()` / `.resetFields()` |
|
|
94
|
-
|
|
95
|
-
## ProForm 最小示例
|
|
96
|
-
|
|
97
|
-
```vue
|
|
98
|
-
<script setup lang="ts">
|
|
99
|
-
import { ProForm, useForm } from '@qin-ui/element-plus-pro';
|
|
100
|
-
interface User {
|
|
101
|
-
username: string;
|
|
102
|
-
age: number;
|
|
103
|
-
gender: string;
|
|
104
|
-
}
|
|
105
|
-
const form = useForm<User>({ username: '', age: 18, gender: 'male' }, [
|
|
106
|
-
{
|
|
107
|
-
path: 'username',
|
|
108
|
-
component: 'input',
|
|
109
|
-
label: '用户名',
|
|
110
|
-
rules: [{ required: true, trigger: 'blur' }],
|
|
111
|
-
},
|
|
112
|
-
{ path: 'age', component: 'input-number', label: '年龄', min: 1, max: 150 },
|
|
113
|
-
{
|
|
114
|
-
path: 'gender',
|
|
115
|
-
component: 'select',
|
|
116
|
-
label: '性别',
|
|
117
|
-
options: [
|
|
118
|
-
{ label: '男', value: 'male' },
|
|
119
|
-
{ label: '女', value: 'female' },
|
|
120
|
-
],
|
|
121
|
-
},
|
|
122
|
-
]);
|
|
123
|
-
const submit = async () => {
|
|
124
|
-
await form.formRef.value?.validate();
|
|
125
|
-
console.log(form.formData);
|
|
126
|
-
};
|
|
127
|
-
</script>
|
|
128
|
-
<template>
|
|
129
|
-
<ProForm :form="form" />
|
|
130
|
-
<el-button type="primary" @click="submit">提交</el-button>
|
|
131
|
-
</template>
|
|
132
|
-
```
|
|
77
|
+
### 不支持响应式的属性(不能包 ref/computed)
|
|
133
78
|
|
|
134
|
-
|
|
79
|
+
`component` / `formItemContainer` / `componentContainer` / `valueFormatter` / `fields` / `slots` / `modelProp`。
|
|
135
80
|
|
|
136
|
-
|
|
137
|
-
`teleport 插槽注入` > `ProComponentProvider.componentMap` > `内置 componentMap` > `原始 component 值`
|
|
81
|
+
## 实例成员速查
|
|
138
82
|
|
|
139
|
-
###
|
|
140
|
-
|
|
141
|
-
`component` 直接传组件对象,**必须用 `markRaw` 包裹**。
|
|
83
|
+
### useForm -- 表单实例
|
|
142
84
|
|
|
143
85
|
```ts
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
{ path: 'code', label: '验证码', component: markRaw(MyInput) }
|
|
86
|
+
useForm(initFormData, Field[], root = true) // 重载一(常用):初始数据 + 字段配置
|
|
87
|
+
useForm(true | false) // 重载二:仅拿实例(root)
|
|
147
88
|
```
|
|
148
89
|
|
|
149
|
-
|
|
150
|
-
> 类型上 `component` 接受 `RenderComponentType | Raw<RenderComponentType>`,`Raw<T>` 即 markRaw 的类型标记。
|
|
151
|
-
> 此字段不支持响应式(不能包 ref/computed)。
|
|
90
|
+
返回 `Form` 实例(**`formData` 是 reactive 对象,不用 `.value`**):
|
|
152
91
|
|
|
153
|
-
|
|
92
|
+
| 成员 | 说明 |
|
|
93
|
+
| :------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------- |
|
|
94
|
+
| `form.formData` | 响应式数据,可直接读写,支持深层路径 `formData.address.city` |
|
|
95
|
+
| `form.getFormData(path)` | 路径读取;无参返回 `undefined` |
|
|
96
|
+
| `form.setFormData(path, value)` / `setFormData(path, prev=>new)` | 路径写入,支持函数式 |
|
|
97
|
+
| `form.setFormData({...})` / `setFormData(prev => ({...prev, name:'新'}))` | 批量覆盖整个表单,支持函数式(先清空再写入) |
|
|
98
|
+
| `form.fields` | 字段配置数组(Ref) |
|
|
99
|
+
| `form.getField(path)` / `getField(fn)` | 字段查找,支持路径或查找函数;`{all:true}` 返回所有匹配数组 |
|
|
100
|
+
| `form.setField(path, patch)` / `setField(path, prev=>({...}))` | 字段增改查;默认合并,`{updateType:'rewrite'}` 覆盖;支持函数式更新;`{all:true}` 批量更新所有匹配 |
|
|
101
|
+
| `form.deleteField` / `form.appendField` / `form.prependField` / `form.getParentField` | 字段增删查;均支持 `{all:true}`;`appendField(undefined, f)` 末尾追加、`prependField(undefined, f)` 开头插入,入参可为数组 |
|
|
102
|
+
| `form.formRef` | 底层 element-plus Form 实例引用(Ref),`formRef.value?.validate()` / `.resetFields()` |
|
|
154
103
|
|
|
155
|
-
|
|
104
|
+
### useTable -- 表格实例
|
|
156
105
|
|
|
157
106
|
```ts
|
|
158
|
-
|
|
159
|
-
import MyInput from './MyInput.vue';
|
|
160
|
-
{ path: 'code', label: '验证码', component: (p, ctx) => h(MyInput, { ...p, ...ctx.attrs }) }
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### 方式 3:ProComponentProvider 注入 componentMap(全局复用,推荐多字段场景)
|
|
164
|
-
|
|
165
|
-
在根用 `componentMap` 注册,Field 里用字符串引用。**可覆盖内置组件**(如 `input: MyInput` 替换全局 input)。
|
|
166
|
-
|
|
167
|
-
```vue
|
|
168
|
-
<script setup lang="ts">
|
|
169
|
-
import { ProComponentProvider } from '@qin-ui/element-plus-pro';
|
|
170
|
-
import MyRichTextEditor from './components/MyRichTextEditor.vue';
|
|
171
|
-
const componentMap = { 'rich-editor': MyRichTextEditor };
|
|
172
|
-
</script>
|
|
173
|
-
<template>
|
|
174
|
-
<ProComponentProvider :component-map="componentMap">
|
|
175
|
-
<ProForm :form="form" />
|
|
176
|
-
</ProComponentProvider>
|
|
177
|
-
</template>
|
|
107
|
+
useTable({ columns, data, pageParam, searchParam, searchFields }); // 数据源用 data(非 dataSource)
|
|
178
108
|
```
|
|
179
109
|
|
|
180
|
-
|
|
110
|
+
返回 `Table` 实例(**数据源字段名为 `data`,非 `dataSource`**):
|
|
181
111
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
112
|
+
| 成员 | 说明 |
|
|
113
|
+
| :-------------------------------------------------------------------- | :----------------------------------------------------- |
|
|
114
|
+
| `table.columns` / `table.data` | 列配置 / 数据源(Ref,element-plus 语义) |
|
|
115
|
+
| `table.pageParam` | 分页参数(reactive):`current` / `pageSize` / `total` |
|
|
116
|
+
| `table.searchForm` | 搜索表单实例(Form 类型,所有 useForm 方法可用) |
|
|
117
|
+
| `table.setColumn` / `deleteColumn` / `appendColumn` / `prependColumn` | 列增删改查(用法同 setField,支持 `{all:true}`) |
|
|
118
|
+
| `table.setPageParam(patch)` | 设置分页参数 |
|
|
119
|
+
| `table.resetQueryParams()` | 重置分页到第一页 + 恢复搜索条件到初始值 |
|
|
190
120
|
|
|
191
|
-
|
|
121
|
+
## 关键约定
|
|
192
122
|
|
|
193
|
-
|
|
123
|
+
### 自定义组件
|
|
194
124
|
|
|
195
|
-
|
|
196
|
-
<ProForm :form="form">
|
|
197
|
-
<template #agreement="scoped">
|
|
198
|
-
<el-checkbox v-bind="scoped">同意协议</el-checkbox>
|
|
199
|
-
</template>
|
|
200
|
-
</ProForm>
|
|
201
|
-
```
|
|
125
|
+
`Field.component` 解析优先级(高 -> 低):`teleport 插槽注入` > `ProComponentProvider.componentMap` > `内置 componentMap` > `原始 component 值`。
|
|
202
126
|
|
|
203
|
-
|
|
127
|
+
四种接入方式(完整代码见 skills):
|
|
204
128
|
|
|
205
|
-
-
|
|
206
|
-
-
|
|
207
|
-
-
|
|
208
|
-
-
|
|
129
|
+
- **方式 1** `markRaw(SFC)`:单字段复用 SFC(**必须 markRaw**,否则被 Vue 深度代理触发性能警告)
|
|
130
|
+
- **方式 2** render 函数 `(props, ctx) => VNode`:需动态拼装 props
|
|
131
|
+
- **方式 3** `ProComponentProvider` 注入 `componentMap`:全局复用 / 覆盖内置组件,可追加 `declare module` 声明获强类型
|
|
132
|
+
- **方式 4** 模板 scoped slot:插槽名 = 字段 `path`,`v-bind="scoped"` 转发(teleport 机制,优先级最高)
|
|
209
133
|
|
|
210
|
-
|
|
134
|
+
约定:默认 v-model 绑 `modelValue`,他 prop 用 `modelProp` 指定;组件会收到 `path` prop;除框架级属性外其余作 attrs 透传。
|
|
211
135
|
|
|
212
|
-
|
|
213
|
-
- **接收 path**:组件会收到 `path` prop(字段路径)
|
|
214
|
-
- **属性透传**:Field 上除框架级属性外(component/hidden/modelProp/valueFormatter/fields/slots/formItemContainer/componentContainer/extraProps 等),其余作为 attrs 透传给自定义组件
|
|
136
|
+
### valueFormatter -- 字段值转换
|
|
215
137
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
控制表单值与组件值之间的转换(如日期字符串与对象互转)。**在 onUpdate:modelValue 前(即 v-model 写回前)执行**,支持两种形态:
|
|
138
|
+
控制表单值与组件值之间的转换。**在表单数据写入前(computed setter 中,于 `onUpdate:modelValue` 写回前)执行**,支持两种形态:
|
|
219
139
|
|
|
220
140
|
```ts
|
|
221
|
-
// 函数形态:(新值, 旧值) => 转换后的值,写回 formData
|
|
141
|
+
// 函数形态:(新值, 旧值) => 转换后的值,写回 formData。仅 set(写入)方向生效,读取时不转换
|
|
222
142
|
{ path: 'name', valueFormatter: (val, oldVal) => val?.trim() }
|
|
223
143
|
|
|
224
|
-
// 对象形态:get 读出时转换,set
|
|
144
|
+
// 对象形态:get 读出时转换,set 写入时转换(双向)
|
|
225
145
|
{ path: 'birthday', component: 'date-picker',
|
|
226
|
-
valueFormatter: {
|
|
227
|
-
get: (val) => val ? new Date(val) : null, // formData -> 组件显示
|
|
228
|
-
set: (val) => val ? dayjs(val).format('YYYY-MM-DD') : null, // 组件 -> formData
|
|
229
|
-
} }
|
|
146
|
+
valueFormatter: { get: v => v ? new Date(v) : null, set: v => v ? dayjs(v).format('YYYY-MM-DD') : null } }
|
|
230
147
|
```
|
|
231
148
|
|
|
232
|
-
|
|
149
|
+
### ProTable -- 配置驱动表格
|
|
233
150
|
|
|
234
|
-
|
|
235
|
-
const table = useTable<SearchParams, User>({
|
|
236
|
-
columns: [{ prop: 'name', label: '姓名', width: 120 }],
|
|
237
|
-
data: [], // 数据源(element-plus 用 data,非 dataSource)
|
|
238
|
-
pageParam: { current: 1, pageSize: 10, total: 0 }, // 默认值
|
|
239
|
-
searchParam: { keyword: '', status: '' },
|
|
240
|
-
searchFields: [ // 与 ProForm 同一套 Field[] 格式
|
|
241
|
-
{ path: 'keyword', component: 'input', label: '关键词' },
|
|
242
|
-
{ path: 'status', component: 'select', label: '状态', options: [...] },
|
|
243
|
-
],
|
|
244
|
-
});
|
|
245
|
-
```
|
|
151
|
+
透传所有 element-plus `TableProps`(`& Omit<TableProps,'data'>`),可直接写 `row-key` / `bordered` / `stripe` 等原生属性;`size`、`loading` 是 v-model。
|
|
246
152
|
|
|
247
|
-
|
|
153
|
+
关键 prop:`table`(useTable 实例)、`search`(数据查询方法 `() => Promise`,ProTable 内部调用,非自动触发)、`addIndexColumn`、`immediateSearch`、`control`、`searchFormConfig`(含 `hidden`/`container`/`layout`/`expand`)、`tableContainer`、`columns`(覆盖实例列配置)、`data`(覆盖实例数据源)、`pagination`(`false` | 分页属性)。
|
|
248
154
|
|
|
249
|
-
|
|
250
|
-
| :-------------------------------------------------------------------- | :----------------------------------------------------- |
|
|
251
|
-
| `table.columns` | 列配置(Ref) |
|
|
252
|
-
| `table.data` | 表格数据源(Ref,element-plus 语义) |
|
|
253
|
-
| `table.pageParam` | 分页参数(reactive):`current` / `pageSize` / `total` |
|
|
254
|
-
| `table.searchForm` | 搜索表单实例(Form 类型,所有 useForm 方法可用) |
|
|
255
|
-
| `table.setColumn` / `deleteColumn` / `appendColumn` / `prependColumn` | 列增删改查(用法同 setField) |
|
|
256
|
-
| `table.setPageParam(patch)` | 设置分页参数 |
|
|
257
|
-
| `table.resetQueryParams()` | 重置分页到第一页 + 恢复搜索条件到初始值 |
|
|
258
|
-
|
|
259
|
-
## ProTable -- 配置驱动表格
|
|
260
|
-
|
|
261
|
-
**关键:ProTable 透传所有 element-plus TableProps**(`& TableProps`),可直接写 `row-key` / `bordered` / `stripe` / `row-selection` 等原生属性;`size`、`loading` 是 v-model。
|
|
262
|
-
|
|
263
|
-
| prop | 说明 |
|
|
264
|
-
| :----------------- | :-------------------------------------------------------------- |
|
|
265
|
-
| `table` | useTable 实例 |
|
|
266
|
-
| `search` | 数据查询方法 `() => Promise`,ProTable 内部调用它(非自动触发) |
|
|
267
|
-
| `addIndexColumn` | 首列插入 index 列 |
|
|
268
|
-
| `immediateSearch` | onMounted 时立即触发一次 search |
|
|
269
|
-
| `control` | 是否显示 size/列控制按钮,可 `{sizeControl, columnControl}` |
|
|
270
|
-
| `searchFormConfig` | 搜索栏配置,含 `hidden`(隐藏搜索区)、`container` |
|
|
271
|
-
| `tableContainer` | 表格区容器 |
|
|
155
|
+
**列控制(control)**:`control` 支持布尔值或 `{ sizeControl, columnControl }` 对象;`columnControl` 可为布尔值或 `ColumnControlConfig`:`excludedKeys`(不在下拉出现、始终展示)、`disabledKeys`(显示但不可取消勾选)、`disableCheckAll`(禁用全选/取消全选)。element-plus 列标题用 `label`(字符串)渲染,无需 labels 映射;列 key 取 `prop` / `columnKey` / 索引。
|
|
272
156
|
|
|
273
157
|
**数据流**:搜索->重置分页到第 1 页->调 `search()`;分页/排序变化->更新 `pageParam`->调 `search()`;重置->`resetQueryParams()`->调 `search()`。
|
|
274
158
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
继承 element-plus `TableColumnCtx`,**所有原生列属性可用**(`prop` / `label` / `width` / `fixed` / `align` / `sortable` / `formatter` / `filters`…)。新增:
|
|
278
|
-
|
|
279
|
-
- `prop`:列数据字段(主用),对应数据源 key
|
|
280
|
-
- `hidden`:隐藏该列(配合列控制,支持响应式)
|
|
281
|
-
- `render(scope)`:自定义渲染函数,接收行 scope,**优先级高于 `formatter`**
|
|
282
|
-
|
|
283
|
-
> element-plus Table 列用 `prop`(不是 `dataIndex`),数据源用 `data`(不是 `dataSource`)。
|
|
284
|
-
|
|
285
|
-
## ProTable 最小示例
|
|
286
|
-
|
|
287
|
-
```vue
|
|
288
|
-
<script setup lang="ts">
|
|
289
|
-
import { ProTable, useTable } from '@qin-ui/element-plus-pro';
|
|
290
|
-
interface User {
|
|
291
|
-
id: number;
|
|
292
|
-
name: string;
|
|
293
|
-
status: string;
|
|
294
|
-
}
|
|
295
|
-
interface Search {
|
|
296
|
-
keyword: string;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
const table = useTable<Search, User>({
|
|
300
|
-
columns: [
|
|
301
|
-
{ prop: 'name', label: '姓名', width: 120 },
|
|
302
|
-
{ prop: 'status', label: '状态' },
|
|
303
|
-
],
|
|
304
|
-
searchFields: [{ path: 'keyword', component: 'input', label: '关键词' }],
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
const fetchData = async () => {
|
|
308
|
-
// 组装查询参数:搜索条件 + 分页
|
|
309
|
-
const res = await api.list({
|
|
310
|
-
...table.searchForm.formData,
|
|
311
|
-
...table.pageParam,
|
|
312
|
-
});
|
|
313
|
-
table.data.value = res.data;
|
|
314
|
-
table.setPageParam({ total: res.total });
|
|
315
|
-
};
|
|
316
|
-
</script>
|
|
317
|
-
<template>
|
|
318
|
-
<ProTable :table="table" :search="fetchData" row-key="id" immediate-search />
|
|
319
|
-
</template>
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
## 响应式联动(三种模式,选最简的)
|
|
159
|
+
### Column -- 列配置
|
|
323
160
|
|
|
324
|
-
|
|
325
|
-
disabled: computed(() => !form.formData.enabled), // A 声明式,初始化时已知(首选)
|
|
326
|
-
const isDisabled = ref(false); // B 外部共享状态
|
|
327
|
-
form.setField('limitCount', { disabled: true }); // C 命令式,事件驱动
|
|
328
|
-
```
|
|
161
|
+
继承 element-plus `TableColumnCtx`(除 `prop`/`property`/`children`/`render`),所有原生列属性可用。新增:`prop`(列数据路径,主用,对应数据源 key)、`key`(辅助标识,优先级更低)、`hidden`(隐藏该列,配合列控制)、`render(scope)`(自定义渲染函数,接收 `{ row, column, $index, cellValue }`,优先级高于 `formatter`)。
|
|
329
162
|
|
|
330
|
-
>
|
|
163
|
+
> element-plus Table 列用 `prop`(不是 `dataIndex`),数据源用 `data`(不是 `dataSource`),v-model 用 `modelValue`(不是 `value`)。
|
|
331
164
|
|
|
332
165
|
## 反模式
|
|
333
166
|
|
|
@@ -340,6 +173,10 @@ form.setField('limitCount', { disabled: true }); // C 命令式,事件驱
|
|
|
340
173
|
|
|
341
174
|
## 按需深查
|
|
342
175
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
-
|
|
176
|
+
完整 API(详细签名、参数表、完整示例、ProTable Slots、ProComponentProvider 用法):
|
|
177
|
+
|
|
178
|
+
- `.agents/skills/element-plus-pro/SKILL.md` — skills 入口(速查 + 参考导航)
|
|
179
|
+
- `.agents/skills/element-plus-pro/references/README.md` — 完整使用文档与进阶示例
|
|
180
|
+
- `.agents/skills/element-plus-pro/references/api.md` — 结构化 API 元数据
|
|
181
|
+
- `node_modules/@qin-ui/element-plus-pro/README.md` — 完整用法与进阶示例
|
|
182
|
+
- element-plus 组件属性查阅官方文档:https://element-plus.org
|
package/README.md
CHANGED
|
@@ -46,7 +46,8 @@ npx @qin-ui/element-plus-pro init-ai
|
|
|
46
46
|
将在项目中生成双载体 AI 上下文,使 Cursor / Claude Code / Codex 等 AI 工具深度理解本库的 Schema 驱动用法与属性透传规则:
|
|
47
47
|
|
|
48
48
|
- `AGENTS.md` - 核心使用规则(跨工具开放约定,会话时自动注入,AI 默认加载)
|
|
49
|
-
- `.agents/skills/element-plus-pro.md`
|
|
49
|
+
- `.agents/skills/element-plus-pro/SKILL.md` — skills 入口(速查 + 参考导航)
|
|
50
|
+
- `.agents/skills/element-plus-pro/references/` — 完整使用文档与结构化 API 元数据
|
|
50
51
|
|
|
51
52
|
> 生成的 `AGENTS.md` 使用标记区块写入,重复执行 `init-ai` 可安全更新,不影响项目内其他库的指令。建议将生成的文件提交到 Git 仓库,团队共享 AI 上下文。
|
|
52
53
|
|
|
@@ -200,21 +201,22 @@ ProForm/ProTable 是渲染引擎,所有真实 UI 来自 element-plus。**Field
|
|
|
200
201
|
|
|
201
202
|
ProComponentProvider 内置了一套默认属性预设,**即使不配置 `component-vars` 也会生效**。Field 配置优先级最高,会覆盖这些预设。以下为各组件的内置默认值(写代码时需知晓,避免行为与预期不符):
|
|
202
203
|
|
|
203
|
-
| component
|
|
204
|
-
|
|
|
205
|
-
| `switch`
|
|
206
|
-
| `input`
|
|
207
|
-
| `input.textarea`
|
|
208
|
-
| `input.password`
|
|
209
|
-
| `input-number`
|
|
210
|
-
| `select` / `cascader` / `
|
|
211
|
-
| `
|
|
212
|
-
| `
|
|
213
|
-
| `pro-form
|
|
214
|
-
| `pro-
|
|
204
|
+
| component | 默认预设 |
|
|
205
|
+
| :-------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
206
|
+
| `switch` | `{ modelProp: 'modelValue' }` -- v-model 绑定 `modelValue`(element-plus 惯例,即 `v-model`) |
|
|
207
|
+
| `input` | `{ maxlength: 100, clearable: true, placeholder: '请输入' }` |
|
|
208
|
+
| `input.textarea` | `{ maxlength: 200, autosize: { minRows: 3, maxRows: 6 }, showWordLimit: true, clearable: true, placeholder: '请输入' }` |
|
|
209
|
+
| `input.password` | `{ showPassword: true, maxlength: 100, clearable: true, placeholder: '请输入' }` |
|
|
210
|
+
| `input-number` | `{ max: 1e15-1, min: -(1e15+1), controls: false, placeholder: '请输入', style: { width: '100%' } }` |
|
|
211
|
+
| `select` / `cascader` / `tree-select` | `{ clearable: true, placeholder: '请选择' }` |
|
|
212
|
+
| `autocomplete` | `{ clearable: true, placeholder: '请输入' }` |
|
|
213
|
+
| `date-picker` / `time-picker` / `time-select` | `{ style: { width: '100%' }, placeholder: '请选择' }` |
|
|
214
|
+
| `pro-form` | `{ grid: { gutter: 24 } }` |
|
|
215
|
+
| `pro-form-item` | `{ span: 8 }` |
|
|
216
|
+
| `pro-table` | `{ pagination: { layout: 'total,sizes,prev,pager,next,jumper', pageSizes: [10,20,30,40,50,100], background: true }, searchFormConfig: { layout: 'grid', expand: { minExpandRows: 2, expandStatus: false } }, control: true, addIndexColumn: true }` |
|
|
215
217
|
|
|
216
218
|
> `modelProp` 控制 v-model 绑定的属性名,element-plus 默认 `'modelValue'`(即 `v-model`)。`switch` 经预设同样为 `modelValue`,通常无需手动设置。
|
|
217
|
-
> `date-picker` 支持按 type 子类型分别预设:`date-picker.date` / `.daterange` / `.datetime` / `.week` / `.month` / `.monthrange` / `.year` / `.yearrange` 等。
|
|
219
|
+
> `date-picker` 支持按 type 子类型分别预设:`date-picker.date` / `.dates` / `.daterange` / `.datetime` / `.datetimerange` / `.week` / `.month` / `.monthrange` / `.months` / `.year` / `.yearrange` / `.years` 等。
|
|
218
220
|
|
|
219
221
|
---
|
|
220
222
|
|
|
@@ -241,7 +243,12 @@ ProComponentProvider 内置了一套默认属性预设,**即使不配置 `comp
|
|
|
241
243
|
| 参数名 | 说明 | 类型 | 默认值 |
|
|
242
244
|
| :----------------- | :-------------------------------------------------------- | :------------------------------------- | :------ |
|
|
243
245
|
| `table` | 由 `useTable` 返回的表格实例 | `Table` | - |
|
|
246
|
+
| `columns` | 覆盖实例列配置,传入后优先于 `table.columns` | `Column[]` | - |
|
|
247
|
+
| `data` | 覆盖实例数据源,传入后优先于 `table.data` | `T[]` | - |
|
|
248
|
+
| `pagination` | 分页配置,传 `false` 禁用分页 | `false \| PaginationProps` | - |
|
|
244
249
|
| `search` | 触发表格查询的回调函数,需返回 Promise 或直接返回查询数据 | `(params: any) => Promise<any> \| any` | - |
|
|
250
|
+
| `size` | 表格尺寸(v-model) | `string` | - |
|
|
251
|
+
| `loading` | 表格加载状态(v-model) | `boolean` | - |
|
|
245
252
|
| `addIndexColumn` | 是否自动在表格首列插入序号列 | `boolean` | `false` |
|
|
246
253
|
| `immediateSearch` | 表格挂载时(onMounted)是否立即触发一次 `search` 查询 | `boolean` | `false` |
|
|
247
254
|
| `control` | 是否在表格右上角工具栏中展示尺寸调节和列动态显示控制按钮 | `boolean` | `true` |
|
|
@@ -302,19 +309,19 @@ const form = useForm<D>(initFormData?, initFields?, root?)
|
|
|
302
309
|
|
|
303
310
|
#### 返回值 (Form 实例)
|
|
304
311
|
|
|
305
|
-
| 属性/方法
|
|
306
|
-
|
|
|
307
|
-
| `formData`
|
|
308
|
-
| `fields`
|
|
309
|
-
| `formRef`
|
|
310
|
-
| `getFormData(path)`
|
|
311
|
-
| `setFormData(path, val)`
|
|
312
|
-
| `getField(path, opts?)`
|
|
313
|
-
| `setField(path, patch, opts?)`
|
|
314
|
-
| `deleteField(path)`
|
|
315
|
-
| `appendField(path, field)`
|
|
316
|
-
| `prependField(path, field)`
|
|
317
|
-
| `getParentField(path)`
|
|
312
|
+
| 属性/方法 | 说明 | 类型 |
|
|
313
|
+
| :--------------------------------- | :----------------------------------------------------------------------------------------------------------------------------- | :------------------------------- |
|
|
314
|
+
| `formData` | 响应式表单数据对象(由 reactive 包装) | `Reactive<D>` |
|
|
315
|
+
| `fields` | 响应式表单字段配置数组引用 | `Ref<Field[]>` |
|
|
316
|
+
| `formRef` | 底层 Element Plus `el-form` 的组件引用实例 | `Ref<FormInstance \| undefined>` |
|
|
317
|
+
| `getFormData(path)` | 安全获取指定字段路径(支持深层 'a.b')的数据值 | `(path) => any` |
|
|
318
|
+
| `setFormData(path, val)` | 安全更新指定路径的值,支持 4 种形态:路径+值、路径+函数、批量对象、函数式批量 `setFormData(prev => ({...}))` | `(path, val) => void` |
|
|
319
|
+
| `getField(path, opts?)` | 获取指定 path 的字段配置,支持查找函数定位,支持配置 `{ all: true }` 获取所有匹配项 | `(path, opts) => Field` |
|
|
320
|
+
| `setField(path, patch, opts?)` | 默认合并更新字段配置;`{updateType:'rewrite'}` 覆盖;支持函数式 `setField(path, prev=>({...}))`;`{all:true}` 批量更新所有匹配 | `(path, patch, opts) => void` |
|
|
321
|
+
| `deleteField(path, opts?)` | 删除字段配置;`{all:true}` 删除所有匹配的字段 | `(path, opts?) => void` |
|
|
322
|
+
| `appendField(path, field, opts?)` | 在指定字段后追加新字段(入参可为数组);`undefined` 在末尾追加;`{all:true}` 所有匹配后追加 | `(path, field, opts?) => void` |
|
|
323
|
+
| `prependField(path, field, opts?)` | 在指定字段前插入新字段(入参可为数组);`undefined` 在开头插入;`{all:true}` 所有匹配前插入 | `(path, field, opts?) => void` |
|
|
324
|
+
| `getParentField(path, opts?)` | 查找父级字段配置;`{all:true}` 返回所有匹配的父级字段 | `(path, opts?) => Field` |
|
|
318
325
|
|
|
319
326
|
---
|
|
320
327
|
|
|
@@ -358,6 +365,7 @@ const table = useTable<D, T>({
|
|
|
358
365
|
- **原生列属性支持**:`prop`、`label`、`width`、`fixed`、`align`、`sortable`、`filters`、`filterMethod`、`children` 等
|
|
359
366
|
- **原生格式化支持**:`formatter`
|
|
360
367
|
- **Pro 级扩展属性**:
|
|
368
|
+
- `key` (辅助标识,优先级低于 `prop`)
|
|
361
369
|
- `hidden` (是否隐藏列,支持响应式)
|
|
362
370
|
- `render(scope)` (自定义渲染插槽,接收行参数)
|
|
363
371
|
|
|
@@ -397,7 +405,7 @@ const table = useTable<D, T>({
|
|
|
397
405
|
|
|
398
406
|
#### `valueFormatter` 字段值转换
|
|
399
407
|
|
|
400
|
-
|
|
408
|
+
控制表单值与组件值之间的转换。在表单数据写入前(computed setter 中,于 `onUpdate:modelValue` 写回前)执行,支持两种形态。**函数形态仅 set(写入)方向生效,读取时不转换;对象形态 get/set 双向生效:**
|
|
401
409
|
|
|
402
410
|
```ts
|
|
403
411
|
// 函数形态:(新值, 旧值) => 转换后的值,写回 formData
|
package/api.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-
|
|
2
|
+
"generatedAt": "2026-08-13T08:59:17.227Z",
|
|
3
3
|
"name": "@qin-ui/element-plus-pro",
|
|
4
4
|
"api": [
|
|
5
5
|
{
|
|
@@ -20,6 +20,12 @@
|
|
|
20
20
|
"type": "Record<ComponentName, any>",
|
|
21
21
|
"optional": true,
|
|
22
22
|
"description": "自定义组件映射"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "locale",
|
|
26
|
+
"type": "Partial<ProLocale>",
|
|
27
|
+
"optional": true,
|
|
28
|
+
"description": "内置文案覆盖,可覆盖任意 locale 文案(如查询/重置/序号/占位符等)"
|
|
23
29
|
}
|
|
24
30
|
],
|
|
25
31
|
"examples": [
|