@qin-ui/element-plus-pro 1.0.7 → 1.0.8
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 +215 -23
- package/api.json +1 -1
- package/bin/init-ai.mjs +214 -52
- package/es/element-plus-pro.css +3 -3
- package/es/table/index.js +1 -1
- package/package.json +1 -1
package/AI-CONTEXT.md
CHANGED
|
@@ -1,37 +1,229 @@
|
|
|
1
|
-
# @qin-ui/element-plus-pro
|
|
1
|
+
# @qin-ui/element-plus-pro — AI 上下文
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
基于 **element-plus**(Vue 3,el- 前缀)的 Schema 驱动高级组件库。用 JS 对象描述 UI,而非模板堆砌组件标签。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
---
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
## 1. 架构概览
|
|
8
|
+
|
|
9
|
+
### 1.1 三层架构
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
┌─────────────────────────────────────────────────┐
|
|
13
|
+
│ Field[] 配置层(用户编写的 JS 对象) │
|
|
14
|
+
│ { path:'name', component:'input', span:8, ... } │
|
|
15
|
+
├─────────────────────────────────────────────────┤
|
|
16
|
+
│ @qin-ui/element-plus-pro(Schema 解析 + 组件解析)│
|
|
17
|
+
│ 属性分层剥离 → Grid→el-col, FormItem→el-form-item, 剩余→输入控件 │
|
|
18
|
+
├─────────────────────────────────────────────────┤
|
|
19
|
+
│ element-plus(Vue 3 组件库,el- 前缀) │
|
|
20
|
+
│ el-input / el-select / el-date-picker / el-table ...│
|
|
21
|
+
└─────────────────────────────────────────────────┘
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
ProForm/ProTable 是**渲染引擎**,不是组件库。Field 属性被逐层剥离,分发到不同层级的 el-* 组件。
|
|
25
|
+
|
|
26
|
+
### 1.2 内置组件映射表
|
|
27
|
+
|
|
28
|
+
| Field `component` | 渲染的 el 组件 | 子类型(`type`) | 常用透传 Props(示例) |
|
|
29
|
+
| :--- | :--- | :--- | :--- |
|
|
30
|
+
| `'input'` | el-input | textarea, password | placeholder, maxlength, clearable, showWordLimit, showPassword, autosize |
|
|
31
|
+
| `'input-number'` | el-input-number | — | min, max, step, precision, controls, placeholder |
|
|
32
|
+
| `'autocomplete'` | el-autocomplete | — | placeholder, clearable, fetchSuggestions, triggerOnFocus |
|
|
33
|
+
| `'select'` | el-select | — | **options**, multiple, filterable, clearable, allowCreate, loading, remote, remoteMethod |
|
|
34
|
+
| `'cascader'` | el-cascader | — | **options**, props, filterable, clearable, showAllLevels |
|
|
35
|
+
| `'date-picker'` | el-date-picker | date, daterange, datetime, datetimerange, week, month, monthrange, year, yearrange | format, valueFormat, disabledDate, clearable, startPlaceholder, endPlaceholder, shortcuts |
|
|
36
|
+
| `'time-picker'` | el-time-picker | — | format, clearable, isRange, startPlaceholder, endPlaceholder |
|
|
37
|
+
| `'time-select'` | el-time-select | — | start, end, step, clearable, minTime, maxTime |
|
|
38
|
+
| `'checkbox-group'` | el-checkbox-group | — | **options**, min, max, disabled |
|
|
39
|
+
| `'radio-group'` | el-radio-group | — | **options**, disabled, size |
|
|
40
|
+
| `'switch'` | el-switch | — | activeText, inactiveText, activeValue, inactiveValue, loading, size |
|
|
41
|
+
| `'slider'` | el-slider | — | min, max, step, showStops, range, marks |
|
|
42
|
+
| `'tree-select'` | el-tree-select | — | **data**, filterable, clearable, checkStrictly, props, multiple, showCheckbox |
|
|
43
|
+
| `'transfer'` | el-transfer | — | **data**, **titles**, filterable, filterMethod, props |
|
|
44
|
+
| `'custom'` | 自定义 | — | component 直接传入 Vue 组件或 h() 渲染函数 |
|
|
45
|
+
|
|
46
|
+
> **编写任何控件属性前,必须查阅 [element-plus 官方文档](https://element-plus.org/) 确认属性名和类型。**
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 2. 属性分层传递(核心规则)
|
|
51
|
+
|
|
52
|
+
Field 属性按渲染目标逐层剥离:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
<el-col :span="8"> <!-- Grid 层 -->
|
|
56
|
+
<el-form-item label="城市"> <!-- FormItem 层 -->
|
|
57
|
+
<el-select v-model="..." placeholder="选择" /> <!-- 输入控件层 -->
|
|
58
|
+
</el-form-item>
|
|
59
|
+
</el-col>
|
|
9
60
|
```
|
|
10
61
|
|
|
11
|
-
|
|
62
|
+
**Grid 层 → `<el-col>`**(仅 grid 启用时):`span`, `offset`, `push`, `pull`, `xs`, `sm`, `md`, `lg`, `xl`
|
|
63
|
+
|
|
64
|
+
**FormItem 层 → `<el-form-item>`**:`label`, `rules`, `error`, `required`, `size`, `showMessage`, `inlineMessage`, `labelWidth`;`formItemClass`/`formItemStyle`→`class`/`style`;`formItemDataAttrs`→`data-*`
|
|
12
65
|
|
|
13
|
-
|
|
66
|
+
**输入控件层 → 输入组件**:其余所有属性(`disabled`, `placeholder`, `clearable`, `options`, `filterable`, `maxlength`, `multiple` 等);`componentClass`/`componentStyle`→`class`/`style`;`componentDataAttrs`→`data-*`
|
|
14
67
|
|
|
15
|
-
|
|
16
|
-
- `ProTable` - 配置驱动表格组件
|
|
17
|
-
- `ProComponentProvider` - 全局配置提供者
|
|
68
|
+
**渲染逻辑消费(不绑定 DOM)**:`component`, `fields`, `hidden`, `slots`, `modelProp`, `valueFormatter`, `componentContainer`, `extraProps`
|
|
18
69
|
|
|
19
|
-
###
|
|
70
|
+
### 2.1 modelProp
|
|
20
71
|
|
|
21
|
-
|
|
22
|
-
- `useFields<D>()` - 字段配置管理
|
|
23
|
-
- `useFormRef()` - 表单组件引用
|
|
24
|
-
- `useTable<D, T>()` - 创建表格实例
|
|
72
|
+
决定 `v-model:xxx` 的绑定变量名:
|
|
25
73
|
|
|
26
|
-
|
|
74
|
+
- 默认 `modelProp: 'modelValue'` → `v-model`(element-plus 惯例)
|
|
75
|
+
- **ProComponentProvider 已为 `switch` 预设 `modelProp: 'modelValue'`**,通常无需手动指定
|
|
76
|
+
- 自定义场景:`modelProp: 'visible'` → `v-model:visible`
|
|
77
|
+
|
|
78
|
+
### 2.2 element-plus 命名约定
|
|
79
|
+
|
|
80
|
+
- 使用 `clearable`(不是 `allowClear`)
|
|
81
|
+
- el-form-item 插槽为 `label` 和 `error`;其他 slot key 透传到底层输入组件(如 el-input 的 `prefix`/`suffix`/`append`/`prepend`)
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 3. 渐进式用法
|
|
86
|
+
|
|
87
|
+
### 第一阶段:基础渲染
|
|
88
|
+
|
|
89
|
+
完全依赖 Field 配置,**禁止手写 `<el-form-item>` 或 `<el-input>`**。
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
const form = useForm({ username: '', password: '' }, [
|
|
93
|
+
{ path: 'username', component: 'input', label: '用户名', placeholder: '请输入',
|
|
94
|
+
rules: [{ required: true, message: '请输入用户名', trigger: 'blur' }] },
|
|
95
|
+
{ path: 'password', component: 'input', type: 'password', label: '密码',
|
|
96
|
+
rules: [{ required: true, message: '请输入密码', trigger: 'blur' }] },
|
|
97
|
+
]);
|
|
98
|
+
// 模板:<ProForm :form="form" />
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 第二阶段:字段联动
|
|
102
|
+
|
|
103
|
+
`disabled`, `hidden`, `rules` 等控制属性支持三种方式:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
// computed() — 声明式,初始化联动首选
|
|
107
|
+
disabled: computed(() => !form.formData.hasLimit),
|
|
108
|
+
|
|
109
|
+
// ref() — 外部共享状态
|
|
110
|
+
const isDisabled = ref(false);
|
|
111
|
+
|
|
112
|
+
// setField() — 运行时命令式
|
|
113
|
+
form.setField('limitCount', { disabled: true });
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**选择:初始化联动→`computed()`;事件触发→`setField()`;共享状态→`ref()`。**
|
|
117
|
+
|
|
118
|
+
### 第三阶段:自定义组件
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
// h() 挂载自定义组件
|
|
122
|
+
{ path: 'key', component: (p, ctx) => h(CustomInput, { ...p, ...ctx.attrs }) }
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```html
|
|
126
|
+
<!-- 同名插槽接管渲染,scoped 内置所有绑定参数 -->
|
|
127
|
+
<ProForm :form="form">
|
|
128
|
+
<template #agreement="scoped">
|
|
129
|
+
<el-checkbox v-bind="scoped">阅读并同意协议</el-checkbox>
|
|
130
|
+
</template>
|
|
131
|
+
</ProForm>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 4. 反模式
|
|
137
|
+
|
|
138
|
+
```html
|
|
139
|
+
<!-- ❌ 禁止在 ProForm 内手写 el-form-item -->
|
|
140
|
+
<ProForm :form="form">
|
|
141
|
+
<el-form-item label="姓名"><el-input v-model="form.formData.name" /></el-form-item>
|
|
142
|
+
</ProForm>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
// ❌ 不查文档盲目猜测 — element-plus 用 filterable,不是 searchable
|
|
147
|
+
{ path: 'city', component: 'select', searchable: true }
|
|
148
|
+
// ✅ 查 element-plus 文档确认后
|
|
149
|
+
{ path: 'city', component: 'select', filterable: true }
|
|
150
|
+
|
|
151
|
+
// span→Grid 层(el-col);placeholder→控件层(el-input)
|
|
152
|
+
{ path: 'name', component: 'input', span: 12, placeholder: '请输入' }
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 5. ProComponentProvider:全局默认配置
|
|
158
|
+
|
|
159
|
+
统一配置子组件默认属性,避免逐字段重复。
|
|
160
|
+
|
|
161
|
+
### INJECT_CONFIG 预设默认值
|
|
162
|
+
|
|
163
|
+
| 组件 | 预设默认值 |
|
|
164
|
+
| :--- | :--- |
|
|
165
|
+
| `switch` | `{ modelProp: 'modelValue' }` |
|
|
166
|
+
| `input` | `{ maxlength: 100, clearable: true, placeholder: '请输入' }` |
|
|
167
|
+
| `input.textarea` | `{ maxlength: 200, autosize: {minRows:3,maxRows:6}, showWordLimit: true, clearable: true, placeholder: '请输入' }` |
|
|
168
|
+
| `input.password` | `{ maxlength: 100, clearable: true, showPassword: true, placeholder: '请输入' }` |
|
|
169
|
+
| `select` / `cascader` | `{ clearable: true, placeholder: '请选择' }` |
|
|
170
|
+
| `input-number` | `{ max: 10^15-1, min: -(10^15+1), controls: false, placeholder: '请输入', style: {width:'100%'} }` |
|
|
171
|
+
| `date-picker` 系列 | `{ style: {width:'100%'} }` + 各子类型专用占位符 |
|
|
172
|
+
| `time-picker` / `time-select` | `{ style: {width:'100%'}, placeholder: '请选择' }` |
|
|
173
|
+
| `tree-select` | `{ clearable: true, placeholder: '请选择' }` |
|
|
174
|
+
| `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 }` |
|
|
175
|
+
| `pro-form` | `{ grid: { gutter: 24 } }` |
|
|
176
|
+
| `pro-form-item` | `{ span: 8 }` |
|
|
177
|
+
|
|
178
|
+
### 优先级(高→低)
|
|
179
|
+
|
|
180
|
+
1. Field 级别配置
|
|
181
|
+
2. `ProComponentProvider` 的 `componentVars` 参数
|
|
182
|
+
3. `INJECT_CONFIG` 内置预设
|
|
183
|
+
|
|
184
|
+
### 覆盖示例
|
|
185
|
+
|
|
186
|
+
```vue
|
|
187
|
+
<template>
|
|
188
|
+
<ProComponentProvider :component-vars="config">
|
|
189
|
+
<ProForm :form="form" />
|
|
190
|
+
</ProComponentProvider>
|
|
191
|
+
</template>
|
|
192
|
+
<script setup lang="ts">
|
|
193
|
+
const config = {
|
|
194
|
+
'pro-form-item': { span: 6 },
|
|
195
|
+
input: { maxlength: 200 },
|
|
196
|
+
select: { filterable: true },
|
|
197
|
+
};
|
|
198
|
+
</script>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 6. ProTable 速览
|
|
204
|
+
|
|
205
|
+
```ts
|
|
206
|
+
const table = useTable<any, Row>({
|
|
207
|
+
columns: [
|
|
208
|
+
{ prop: 'id', label: 'ID', width: 80 },
|
|
209
|
+
{ prop: 'name', label: '姓名', width: 120 },
|
|
210
|
+
],
|
|
211
|
+
// searchFields 与 ProForm fields 格式一致,支持相同分层剥离
|
|
212
|
+
searchFields: [
|
|
213
|
+
{ path: 'name', component: 'input', placeholder: '搜索' },
|
|
214
|
+
{ path: 'status', component: 'select', options: [...] },
|
|
215
|
+
],
|
|
216
|
+
data: [],
|
|
217
|
+
});
|
|
218
|
+
// 模板:<ProTable :table="table" :search="() => fetchData()" immediateSearch />
|
|
219
|
+
```
|
|
27
220
|
|
|
28
|
-
|
|
221
|
+
> element-plus Table Column 用 `prop`(非 `dataIndex`),数据源用 `data`(非 `dataSource`)。
|
|
29
222
|
|
|
30
|
-
|
|
223
|
+
---
|
|
31
224
|
|
|
32
|
-
##
|
|
225
|
+
## 7. 关键参考
|
|
33
226
|
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
-
|
|
37
|
-
- 所有 Element Plus TableColumn 属性
|
|
227
|
+
1. **`node_modules/@qin-ui/element-plus-pro/api.json`** — 结构化 API 元数据
|
|
228
|
+
2. **`node_modules/@qin-ui/element-plus-pro/README.md`** — 完整文档和示例
|
|
229
|
+
3. **[https://element-plus.org/](https://element-plus.org/)** — 确认控件属性时必查
|
package/api.json
CHANGED
package/bin/init-ai.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* @qin-ui
|
|
4
|
+
* @qin-ui/element-plus-pro AI 上下文初始化 CLI 工具
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* 在消费方项目中生成分层 AI 上下文文件,使 AI 工具能够:
|
|
7
|
+
* 1. 理解 @qin-ui/element-plus-pro 的 Schema 驱动架构
|
|
8
|
+
* 2. 掌握属性透传规则(何时查阅 element-plus 文档)
|
|
9
|
+
* 3. 快速获取完整 API 参考
|
|
8
10
|
*
|
|
9
11
|
* 用法:
|
|
10
12
|
* npx @qin-ui/element-plus-pro init-ai
|
|
@@ -28,46 +30,174 @@ const PKG_SHORT = PKG_NAME.replace(/^@qin-ui\//, '');
|
|
|
28
30
|
|
|
29
31
|
// ==================== 终端颜色 ====================
|
|
30
32
|
|
|
31
|
-
const green =
|
|
32
|
-
const cyan =
|
|
33
|
-
const bold =
|
|
34
|
-
const
|
|
33
|
+
const green = s => `\x1b[32m${s}\x1b[0m`;
|
|
34
|
+
const cyan = s => `\x1b[36m${s}\x1b[0m`;
|
|
35
|
+
const bold = s => `\x1b[1m${s}\x1b[0m`;
|
|
36
|
+
const yellow = s => `\x1b[33m${s}\x1b[0m`;
|
|
37
|
+
const dim = s => `\x1b[2m${s}\x1b[0m`;
|
|
35
38
|
|
|
36
|
-
// ====================
|
|
39
|
+
// ==================== 内容读取 ====================
|
|
37
40
|
|
|
38
|
-
function
|
|
39
|
-
const filePath = path.join(PKG_ROOT,
|
|
41
|
+
function readPackageFile(filename) {
|
|
42
|
+
const filePath = path.join(PKG_ROOT, filename);
|
|
40
43
|
if (fs.existsSync(filePath)) {
|
|
41
44
|
return fs.readFileSync(filePath, 'utf-8').trim();
|
|
42
45
|
}
|
|
43
|
-
return
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getAiContextContent() {
|
|
50
|
+
return readPackageFile('AI-CONTEXT.md') || `# ${PKG_NAME}\n\n> 基于 Vue 3 的配置驱动组件库。`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function getReadmeContent() {
|
|
54
|
+
return readPackageFile('README.md') || '';
|
|
44
55
|
}
|
|
45
56
|
|
|
46
|
-
function
|
|
57
|
+
function getApiJsonContent() {
|
|
58
|
+
try {
|
|
59
|
+
const raw = readPackageFile('api.json');
|
|
60
|
+
if (!raw) return null;
|
|
61
|
+
return JSON.parse(raw);
|
|
62
|
+
} catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ==================== 内容生成 ====================
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 生成 rules 文件内容(Instructions 层)
|
|
71
|
+
* 包含:架构关系、透传规则、反模式、element-plus 资源链接
|
|
72
|
+
*/
|
|
73
|
+
function getRulesContent() {
|
|
47
74
|
const aiContext = getAiContextContent();
|
|
48
|
-
const core = [
|
|
49
|
-
aiContext,
|
|
50
|
-
'',
|
|
51
|
-
'## 完整 API 参考',
|
|
52
|
-
'',
|
|
53
|
-
`使用 \`${PKG_NAME}\` 时,请阅读以下文件获取完整的 API 定义、类型签名和使用示例:`,
|
|
54
|
-
`- \`node_modules/${PKG_NAME}/README.md\` — 详细使用文档和代码示例`,
|
|
55
|
-
`- \`node_modules/${PKG_NAME}/api.json\` — 结构化 API 元数据(组件、Hook、类型的签名和 JSDoc 示例)`,
|
|
56
|
-
'',
|
|
57
|
-
].join('\n');
|
|
58
75
|
|
|
59
|
-
// 包含兼容性的 Frontmatter(如 Cursor 支持的 globs 等)
|
|
60
76
|
return [
|
|
61
77
|
'---',
|
|
62
|
-
`description: "${PKG_NAME} 组件库使用规范"`,
|
|
78
|
+
`description: "${PKG_NAME} 组件库使用规范 — Schema 驱动、属性透传规则"`,
|
|
63
79
|
'globs: ["**/*.vue", "**/*.ts", "**/*.tsx"]',
|
|
64
80
|
'alwaysApply: false',
|
|
65
81
|
'---',
|
|
66
82
|
'',
|
|
67
|
-
|
|
83
|
+
aiContext,
|
|
84
|
+
'',
|
|
85
|
+
'---',
|
|
86
|
+
'',
|
|
87
|
+
'## 本地参考文件',
|
|
88
|
+
'',
|
|
89
|
+
'本规则文件提供了核心架构和用法指南。需要完整 API 参考时,请阅读以下文件:',
|
|
90
|
+
'',
|
|
91
|
+
`- **\`.agents/docs/${PKG_SHORT}-api.md\`** — 完整 API 文档(组件、Hooks、类型、Field 配置参考)`,
|
|
92
|
+
`- **\`node_modules/${PKG_NAME}/api.json\`** — 结构化 API 元数据(函数签名、类型定义)`,
|
|
93
|
+
'',
|
|
94
|
+
'## element-plus 文档资源',
|
|
95
|
+
'',
|
|
96
|
+
'所有在 Field 配置中编写的非保留属性,最终会透传给 element-plus 组件。编写前务必查阅文档确认属性名:',
|
|
97
|
+
'',
|
|
98
|
+
'| 资源 | URL | 说明 |',
|
|
99
|
+
'|:--|:--|:--|',
|
|
100
|
+
'| element-plus 官网 | https://element-plus.org/ | 官方文档首页(中文/英文) |',
|
|
101
|
+
'| 组件文档 | https://element-plus.org/zh-CN/component/button | 组件 API 参考入口(中文) |',
|
|
102
|
+
'',
|
|
68
103
|
].join('\n');
|
|
69
104
|
}
|
|
70
105
|
|
|
106
|
+
/**
|
|
107
|
+
* 生成 API 文档内容(Resources 层)
|
|
108
|
+
* 从 README.md + api.json 合并提取完整 API 参考
|
|
109
|
+
*/
|
|
110
|
+
function getApiDocContent() {
|
|
111
|
+
const readme = getReadmeContent();
|
|
112
|
+
const apiJson = getApiJsonContent();
|
|
113
|
+
|
|
114
|
+
const sections = [];
|
|
115
|
+
|
|
116
|
+
sections.push(`# ${PKG_NAME} — 完整 API 参考`, '');
|
|
117
|
+
sections.push(`> 自动生成自 README.md 和 api.json。版本: ${PKG_JSON.version}`, '');
|
|
118
|
+
|
|
119
|
+
// README 内容(已包含完整的使用文档)
|
|
120
|
+
if (readme) {
|
|
121
|
+
sections.push(readme);
|
|
122
|
+
sections.push('');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// 结构化 API 元数据
|
|
126
|
+
if (apiJson && apiJson.api && apiJson.api.length > 0) {
|
|
127
|
+
sections.push('---');
|
|
128
|
+
sections.push('');
|
|
129
|
+
sections.push('## 结构化 API 元数据(自动提取自源码 JSDoc)');
|
|
130
|
+
sections.push('');
|
|
131
|
+
|
|
132
|
+
for (const item of apiJson.api) {
|
|
133
|
+
const typeLabel = {
|
|
134
|
+
component: '组件',
|
|
135
|
+
function: '函数/Hook',
|
|
136
|
+
type: '类型',
|
|
137
|
+
interface: '接口',
|
|
138
|
+
constant: '常量',
|
|
139
|
+
}[item.type] || '';
|
|
140
|
+
|
|
141
|
+
sections.push(`### ${typeLabel} \`${item.name}\``);
|
|
142
|
+
sections.push('');
|
|
143
|
+
sections.push(`**类型:** ${item.type}`);
|
|
144
|
+
if (item.signature) {
|
|
145
|
+
sections.push('');
|
|
146
|
+
sections.push('```typescript');
|
|
147
|
+
sections.push(item.signature);
|
|
148
|
+
sections.push('```');
|
|
149
|
+
}
|
|
150
|
+
if (item.description) {
|
|
151
|
+
sections.push('');
|
|
152
|
+
sections.push(item.description);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (item.typeParams && item.typeParams.length > 0) {
|
|
156
|
+
sections.push('');
|
|
157
|
+
sections.push('**泛型参数:**');
|
|
158
|
+
for (const tp of item.typeParams) {
|
|
159
|
+
const extras = [];
|
|
160
|
+
if (tp.extends) extras.push(`extends ${tp.extends}`);
|
|
161
|
+
if (tp.default) extras.push(`默认 ${tp.default}`);
|
|
162
|
+
const extra = extras.length ? ` (${extras.join(', ')})` : '';
|
|
163
|
+
sections.push(`- \`${tp.name}\`${extra}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (item.params && item.params.length > 0) {
|
|
168
|
+
sections.push('');
|
|
169
|
+
sections.push('**参数:**');
|
|
170
|
+
sections.push('');
|
|
171
|
+
sections.push('| 参数名 | 类型 | 可选 | 描述 |');
|
|
172
|
+
sections.push('| :--- | :--- | :--- | :--- |');
|
|
173
|
+
for (const p of item.params) {
|
|
174
|
+
sections.push(`| \`${p.name}\` | \`${p.type}\` | ${p.optional ? '是' : '否'} | ${p.description} |`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (item.returns) {
|
|
179
|
+
sections.push('');
|
|
180
|
+
sections.push(`**返回值:** ${item.returns}`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (item.examples && item.examples.length > 0) {
|
|
184
|
+
sections.push('');
|
|
185
|
+
sections.push('**示例:**');
|
|
186
|
+
for (const ex of item.examples) {
|
|
187
|
+
sections.push('');
|
|
188
|
+
sections.push(ex);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
sections.push('');
|
|
193
|
+
sections.push('---');
|
|
194
|
+
sections.push('');
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return sections.join('\n');
|
|
199
|
+
}
|
|
200
|
+
|
|
71
201
|
// ==================== 文件写入 ====================
|
|
72
202
|
|
|
73
203
|
function ensureDir(dirPath) {
|
|
@@ -76,31 +206,43 @@ function ensureDir(dirPath) {
|
|
|
76
206
|
}
|
|
77
207
|
}
|
|
78
208
|
|
|
209
|
+
function writeFileWithLog(filePath, content, label) {
|
|
210
|
+
const dir = path.dirname(filePath);
|
|
211
|
+
ensureDir(dir);
|
|
212
|
+
const existed = fs.existsSync(filePath);
|
|
213
|
+
fs.writeFileSync(filePath, content, 'utf-8');
|
|
214
|
+
const status = existed ? yellow('[更新]') : green('[创建]');
|
|
215
|
+
console.log(` ${status} ${cyan(label)}`);
|
|
216
|
+
}
|
|
217
|
+
|
|
79
218
|
// ==================== CLI 入口 ====================
|
|
80
219
|
|
|
81
220
|
function printHelp() {
|
|
82
221
|
console.log(`
|
|
83
|
-
${bold(`${PKG_NAME} CLI
|
|
222
|
+
${bold(`${PKG_NAME} CLI — AI 上下文初始化`)}
|
|
84
223
|
|
|
85
224
|
${bold('用法:')}
|
|
86
225
|
npx ${PKG_NAME} init-ai
|
|
87
226
|
|
|
88
|
-
${bold('
|
|
89
|
-
|
|
227
|
+
${bold('说明:')}
|
|
228
|
+
在项目中生成分层 AI 上下文文件,使 AI 工具能够深度理解和规范使用 ${PKG_NAME}。
|
|
229
|
+
|
|
230
|
+
生成的文件结构:
|
|
231
|
+
.agents/
|
|
232
|
+
rules/
|
|
233
|
+
${PKG_SHORT}.md 规则文件(架构、透传规则、反模式)
|
|
234
|
+
docs/
|
|
235
|
+
${PKG_SHORT}-api.md API 参考(完整文档 + 结构化元数据)
|
|
90
236
|
|
|
91
237
|
${bold('选项:')}
|
|
92
238
|
--help 显示帮助信息
|
|
93
|
-
|
|
94
|
-
${bold('说明:')}
|
|
95
|
-
该命令将采用统一的 Agentic 标准,在项目的 .agents/rules/ 目录下
|
|
96
|
-
生成上下文文件。兼容支持读取 .agents 的主流 AI IDE 和 CLI 工具。
|
|
97
239
|
`);
|
|
98
240
|
}
|
|
99
241
|
|
|
100
242
|
function main() {
|
|
101
243
|
const args = process.argv.slice(2);
|
|
102
|
-
const subcommand = args.find(
|
|
103
|
-
const flags = args.filter(
|
|
244
|
+
const subcommand = args.find(a => !a.startsWith('-'));
|
|
245
|
+
const flags = args.filter(a => a.startsWith('-'));
|
|
104
246
|
|
|
105
247
|
if (!subcommand || flags.includes('--help') || flags.includes('-h')) {
|
|
106
248
|
printHelp();
|
|
@@ -108,35 +250,55 @@ function main() {
|
|
|
108
250
|
}
|
|
109
251
|
|
|
110
252
|
if (subcommand !== 'init-ai') {
|
|
111
|
-
console.error(
|
|
253
|
+
console.error(`\n ❌ 未知命令: ${subcommand}\n`);
|
|
112
254
|
printHelp();
|
|
113
255
|
process.exit(1);
|
|
114
256
|
}
|
|
115
257
|
|
|
116
258
|
console.log('');
|
|
117
|
-
console.log(bold(`📦 ${PKG_NAME} — AI 上下文初始化
|
|
259
|
+
console.log(bold(`📦 ${PKG_NAME} — AI 上下文初始化 v${PKG_JSON.version}`));
|
|
260
|
+
console.log(dim(` 基于 element-plus 的 Schema 驱动组件库`));
|
|
118
261
|
console.log('');
|
|
119
|
-
|
|
120
|
-
const content = getUnifiedAgentContent();
|
|
121
|
-
const dirPath = '.agents/rules';
|
|
122
|
-
const fileName = `${PKG_SHORT}.md`;
|
|
123
|
-
|
|
124
|
-
const fullDir = path.join(process.cwd(), dirPath);
|
|
125
|
-
const fullPath = path.join(fullDir, fileName);
|
|
126
262
|
|
|
127
|
-
|
|
128
|
-
|
|
263
|
+
// 1. 生成 Rules 文件
|
|
264
|
+
console.log(bold('📋 规则层 (Rules)'));
|
|
265
|
+
const rulesContent = getRulesContent();
|
|
266
|
+
writeFileWithLog(
|
|
267
|
+
path.join(process.cwd(), '.agents/rules', `${PKG_SHORT}.md`),
|
|
268
|
+
rulesContent,
|
|
269
|
+
`.agents/rules/${PKG_SHORT}.md`
|
|
270
|
+
);
|
|
271
|
+
console.log(dim(' → 架构概览、属性透传决策树、渐进用法、反模式'));
|
|
272
|
+
console.log('');
|
|
129
273
|
|
|
130
|
-
|
|
131
|
-
console.log(
|
|
274
|
+
// 2. 生成 API 文档
|
|
275
|
+
console.log(bold('📖 参考层 (Docs)'));
|
|
276
|
+
const apiDocContent = getApiDocContent();
|
|
277
|
+
writeFileWithLog(
|
|
278
|
+
path.join(process.cwd(), '.agents/docs', `${PKG_SHORT}-api.md`),
|
|
279
|
+
apiDocContent,
|
|
280
|
+
`.agents/docs/${PKG_SHORT}-api.md`
|
|
281
|
+
);
|
|
282
|
+
console.log(dim(' → 完整 README 文档 + 结构化 API 元数据'));
|
|
283
|
+
console.log('');
|
|
132
284
|
|
|
285
|
+
// 3. 完成提示
|
|
286
|
+
console.log(green('✅ 完成!已生成分层 AI 上下文文件。'));
|
|
133
287
|
console.log('');
|
|
134
|
-
console.log(
|
|
288
|
+
console.log(`${bold('📂 生成的文件:')}`);
|
|
289
|
+
console.log(` ${cyan('.agents/')}`);
|
|
290
|
+
console.log(` ├── ${cyan('rules/')}`);
|
|
291
|
+
console.log(` │ └── ${cyan(PKG_SHORT + '.md')} ${dim('← 核心规则(AI 优先读取)')}`);
|
|
292
|
+
console.log(` └── ${cyan('docs/')}`);
|
|
293
|
+
console.log(` └── ${cyan(PKG_SHORT + '-api.md')} ${dim('← 完整 API 参考')}`);
|
|
294
|
+
console.log('');
|
|
295
|
+
|
|
296
|
+
console.log(`${bold('🔄 建议的下一步:')}`);
|
|
297
|
+
console.log(` 1. 提交 ${cyan('.agents/')} 目录到 Git 仓库,团队共享`);
|
|
298
|
+
console.log(` 2. 查阅 element-plus 官方文档确认组件属性:`);
|
|
299
|
+
console.log(` ${cyan('https://element-plus.org/')}`);
|
|
300
|
+
console.log(` 3. ${dim('(可选)将 element-plus 常用组件 API 速查加入项目文档')}`);
|
|
135
301
|
console.log('');
|
|
136
|
-
console.log(`${bold('下一步:')}`);
|
|
137
|
-
console.log(
|
|
138
|
-
` 将 ${cyan(dirPath)} 目录提交到 Git,团队即可自动享受 AI 增强\n`
|
|
139
|
-
);
|
|
140
302
|
}
|
|
141
303
|
|
|
142
304
|
main();
|
package/es/element-plus-pro.css
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
[class*='-form-item'] [class*='-form-item'][data-v-1dd9fcdd] {
|
|
2
2
|
margin-bottom: 18px;
|
|
3
3
|
}
|
|
4
|
-
.pro-table_search-form[data-v-
|
|
4
|
+
.pro-table_search-form[data-v-d286f62d] [class*='-form-item'] {
|
|
5
5
|
margin: 0;
|
|
6
6
|
}
|
|
7
|
-
.pro-table_search-form_expand-toggle-button[data-v-
|
|
7
|
+
.pro-table_search-form_expand-toggle-button[data-v-d286f62d] {
|
|
8
8
|
display: flex;
|
|
9
9
|
align-items: center;
|
|
10
10
|
padding: 0;
|
|
11
11
|
padding-left: 4px;
|
|
12
12
|
}
|
|
13
|
-
.pro-table_search-form .transition[data-v-
|
|
13
|
+
.pro-table_search-form .transition[data-v-d286f62d] {
|
|
14
14
|
transition: all 0.25s;
|
|
15
15
|
}
|
|
16
16
|
.pro-table_search-form-container[data-v-45e627f4] {
|
package/es/table/index.js
CHANGED
|
@@ -227,7 +227,7 @@ const _sfc_main$8 = /* @__PURE__ */ defineComponent({
|
|
|
227
227
|
};
|
|
228
228
|
}
|
|
229
229
|
});
|
|
230
|
-
const SearchForm = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-
|
|
230
|
+
const SearchForm = /* @__PURE__ */ _export_sfc(_sfc_main$8, [["__scopeId", "data-v-d286f62d"]]);
|
|
231
231
|
const _sfc_main$7 = {};
|
|
232
232
|
const _hoisted_1$4 = { class: "pro-table_search-form-container" };
|
|
233
233
|
function _sfc_render$3(_ctx, _cache) {
|