@qilitt-mickey/vue3-temp-skill 1.0.12 → 1.1.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 +66 -214
- package/SKILL.md +165 -527
- package/package.json +2 -2
- package/references/api-check.md +187 -128
- package/references/base-code-dict.md +49 -48
- package/references/chart-echarts.md +61 -0
- package/references/code-quality.md +44 -15
- package/references/core-kernel.md +305 -0
- package/references/crud-pages.md +87 -261
- package/references/data-compare.md +502 -501
- package/references/data-mapping.md +218 -213
- package/references/data-screen.md +94 -79
- package/references/data-writeback.md +104 -104
- package/references/detail-page.md +100 -99
- package/references/directives-advanced.md +27 -4
- package/references/download-export.md +70 -68
- package/references/feedback-loading.md +62 -60
- package/references/feedback-ui.md +125 -111
- package/references/file-management.md +28 -7
- package/references/flowchart-g6.md +249 -244
- package/references/form-advanced.md +264 -26
- package/references/graph-relation.md +12 -7
- package/references/http-api.md +138 -103
- package/references/icons.md +326 -0
- package/references/layout-theme.md +1 -1
- package/references/mobile-h5.md +20 -0
- package/references/particles.md +143 -0
- package/references/permission-auth.md +8 -31
- package/references/project-inventory.md +175 -120
- package/references/qrcode-barcode.md +107 -92
- package/references/rich-text.md +85 -73
- package/references/seamless-scroll.md +40 -38
- package/references/table-vxe.md +114 -0
- package/references/tree-table.md +2 -1
- package/references/ui-components.md +5 -1
- package/references/verify-captcha.md +110 -96
- package/references/websocket-realtime.md +2 -1
- package/references/wechat-js.md +58 -0
- package/references/workflow-bpmn.md +207 -206
- package/references/advanced-ui.md +0 -302
- package/references/build-optim.md +0 -282
- package/references/vue-core.md +0 -209
|
@@ -1,24 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill: form-advanced
|
|
3
|
+
description: 弹窗(ReDialog / ReDialogResize)、远程下拉、级联、锚点、卡片选择、地址解析等高级表单能力。图标选择完整规范见 icons 模块。
|
|
4
|
+
scope: project
|
|
5
|
+
tags: [form, dialog, ReDialog, ReDialogResize, ReSelectQuery, ReCascader, iconPicker, anchor, address-parse]
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
# 高级表单组件
|
|
2
9
|
|
|
3
|
-
|
|
10
|
+
> 核心选择器与 CRUD 列表筛选项高频相关。
|
|
11
|
+
> **弹窗**:业务弹窗统一用 `ReDialog` / `ReDialogResize`,禁止业务页直接堆裸 `el-dialog`(除非用户明确要求)。
|
|
12
|
+
|
|
13
|
+
## 依赖(缺则先装)
|
|
14
|
+
|
|
15
|
+
按用到的能力安装(先查 `package.json`):
|
|
16
|
+
|
|
17
|
+
| 能力 | 包 | 版本 |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| 地址解析 | `address-parse` | `1.2.19` |
|
|
20
|
+
| 卡片选择 ReCheckCard | `plus-pro-components` | `0.1.31` |
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm add address-parse@1.2.19 plus-pro-components@0.1.31
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`ReDialog` / `ReDialogResize` / `ReSelectQuery` / `ReCascader` / `ReIconPicker` / `ReAnchor` 为项目封装,**无额外 npm 包**。
|
|
27
|
+
|
|
28
|
+
## ReSelectQuery(远程搜索下拉)
|
|
29
|
+
|
|
30
|
+
真实 props 以组件为准:`url` / `value` / `label` / `multiple` / `edit-data` / `handle-result` 等(**不是** `:api` + `label-key`)。
|
|
31
|
+
|
|
32
|
+
```vue
|
|
33
|
+
<script setup lang="ts">
|
|
34
|
+
import { ReSelectQuery } from "@/components/ReSelectQuery";
|
|
35
|
+
|
|
36
|
+
defineOptions({ name: "UserSelectDemo" });
|
|
37
|
+
|
|
38
|
+
const formData = reactive({
|
|
39
|
+
userCode: "",
|
|
40
|
+
userCodeBack: "WR0173",
|
|
41
|
+
userBackData: [{ userCode: "WR0173", userName: "示例用户" }],
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
function handleResult(data: Record<string, unknown>[], totalCount: number, key?: string) {
|
|
45
|
+
data.forEach((item) => {
|
|
46
|
+
item.showText = `【${item.userCode}】${item.userName}`;
|
|
47
|
+
item.keyWords = key || "";
|
|
48
|
+
});
|
|
49
|
+
return { content: data, totalCount };
|
|
50
|
+
}
|
|
51
|
+
</script>
|
|
52
|
+
|
|
53
|
+
<template>
|
|
54
|
+
<ReSelectQuery
|
|
55
|
+
v-model="formData.userCode"
|
|
56
|
+
value="userCode"
|
|
57
|
+
label="userName"
|
|
58
|
+
url="/TMdmIpsUserApi/searchTMdmIpsUserPage"
|
|
59
|
+
/>
|
|
60
|
+
<ReSelectQuery
|
|
61
|
+
v-model="formData.userCodeBack"
|
|
62
|
+
value="userCode"
|
|
63
|
+
label="showText"
|
|
64
|
+
url="/TMdmIpsUserApi/searchTMdmIpsUserPage"
|
|
65
|
+
:handle-result="handleResult"
|
|
66
|
+
:edit-data="formData.userBackData"
|
|
67
|
+
/>
|
|
68
|
+
</template>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## ReCascader(异步级联)
|
|
72
|
+
|
|
73
|
+
```vue
|
|
74
|
+
<script setup lang="ts">
|
|
75
|
+
import { ReCascader } from "@/components/ReCascader";
|
|
76
|
+
|
|
77
|
+
const region = ref<string[]>([]);
|
|
78
|
+
</script>
|
|
79
|
+
|
|
80
|
+
<template>
|
|
81
|
+
<ReCascader v-model="region" :placeholder="$t('请选择')" />
|
|
82
|
+
</template>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
用法细节(懒加载、compare-config)以组件 props / `data-compare` 为准。
|
|
4
86
|
|
|
5
87
|
## ReIconPicker 图标选择器
|
|
6
88
|
|
|
89
|
+
> **完整规范见 `icons` 模块**(命名规则、本地 SVG、菜单 `meta.icon`、UnoCSS、内网离线)。此处仅保留表单场景速览。
|
|
90
|
+
|
|
7
91
|
```vue
|
|
8
92
|
<script setup lang="ts">
|
|
9
|
-
import ReIconPicker from "@/components/ReIconPicker";
|
|
93
|
+
import { ReIconPicker } from "@/components/ReIconPicker";
|
|
10
94
|
|
|
11
95
|
const icon = ref("");
|
|
12
96
|
</script>
|
|
13
97
|
|
|
14
98
|
<template>
|
|
15
99
|
<ReIconPicker v-model="icon" clearable />
|
|
100
|
+
<svg-icon v-if="icon" :name="icon" :size="18" />
|
|
16
101
|
</template>
|
|
17
102
|
```
|
|
18
103
|
|
|
19
|
-
-
|
|
20
|
-
- 支持搜索、分页、自定义 `sources`。
|
|
21
|
-
- 选中值存储为图标名称字符串。
|
|
104
|
+
- 选中值用于 `svg-icon` 的 `name`(本地无冒号;ep/ri 多为 `i-ep:xxx` / `i-ri:xxx`)。
|
|
22
105
|
|
|
23
106
|
## ReSegmented 分段控制器
|
|
24
107
|
|
|
@@ -35,16 +118,14 @@ const active = ref(0);
|
|
|
35
118
|
</script>
|
|
36
119
|
|
|
37
120
|
<template>
|
|
38
|
-
<ReSegmented v-model="active" :options="options"
|
|
121
|
+
<ReSegmented v-model="active" :options="options" />
|
|
39
122
|
</template>
|
|
40
123
|
```
|
|
41
124
|
|
|
42
|
-
- `block`:宽度铺满父容器。
|
|
43
|
-
- `resize`:内容变化时自动重算滑块位置。
|
|
44
|
-
- `options` 支持 `icon`、`tip`、`disabled`。
|
|
45
|
-
|
|
46
125
|
## ReCheckCard 卡片选择
|
|
47
126
|
|
|
127
|
+
依赖 `plus-pro-components@0.1.31`(缺则见文首安装命令)。
|
|
128
|
+
|
|
48
129
|
```vue
|
|
49
130
|
<script setup lang="ts">
|
|
50
131
|
import ReCheckCard from "@/components/ReCheckCard";
|
|
@@ -58,14 +139,11 @@ const options = [
|
|
|
58
139
|
|
|
59
140
|
<template>
|
|
60
141
|
<ReCheckCard v-model="value" :options="options" />
|
|
61
|
-
<ReCheckCard v-model="values" :options="options" multiple />
|
|
62
142
|
</template>
|
|
63
143
|
```
|
|
64
144
|
|
|
65
145
|
## ReAnchor 锚点导航
|
|
66
146
|
|
|
67
|
-
用于长表单/详情页模块跳转。
|
|
68
|
-
|
|
69
147
|
```vue
|
|
70
148
|
<script setup lang="ts">
|
|
71
149
|
import { ReAnchor } from "@/components/ReAnchor";
|
|
@@ -78,14 +156,12 @@ const modules = [
|
|
|
78
156
|
|
|
79
157
|
<template>
|
|
80
158
|
<ReAnchor :anchor-modules="modules" />
|
|
81
|
-
|
|
82
159
|
<div id="baseInfo">...</div>
|
|
83
160
|
<div id="contactInfo">...</div>
|
|
84
161
|
</template>
|
|
85
162
|
```
|
|
86
163
|
|
|
87
|
-
|
|
88
|
-
- `instanceId` 用于多实例区分相同 ID。
|
|
164
|
+
弹窗内指定 `scrollContent`。
|
|
89
165
|
|
|
90
166
|
## ReCollapsible 可折叠面板
|
|
91
167
|
|
|
@@ -103,19 +179,14 @@ const collapsed = ref(false);
|
|
|
103
179
|
</template>
|
|
104
180
|
```
|
|
105
181
|
|
|
106
|
-
- 支持 `left` / `right` 位置。
|
|
107
|
-
- 暴露 `toggle()` 与 `collapsed` 状态。
|
|
108
|
-
|
|
109
182
|
## 地址解析
|
|
110
183
|
|
|
111
|
-
```
|
|
112
|
-
<script setup lang="ts">
|
|
184
|
+
```typescript
|
|
113
185
|
import AddressParse, { Utils } from "address-parse";
|
|
114
186
|
|
|
115
187
|
function parseAddress(text: string) {
|
|
116
188
|
const [result] = AddressParse.parse(text);
|
|
117
189
|
const codeArr = Utils.getTargetAreaListByCode("province", result.code, true);
|
|
118
|
-
|
|
119
190
|
return {
|
|
120
191
|
name: result.name,
|
|
121
192
|
phone: result.mobile || result.phone,
|
|
@@ -125,13 +196,180 @@ function parseAddress(text: string) {
|
|
|
125
196
|
areaCode: codeArr[2]?.code,
|
|
126
197
|
};
|
|
127
198
|
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## ReDialog 通用弹窗(必用)
|
|
204
|
+
|
|
205
|
+
> 落点:`src/components/ReDialog`。基于 `el-dialog` 封装:居中、可拖拽、`destroy-on-close`、默认禁止点遮罩关闭、可选全屏切换、内容区 `el-scrollbar`。
|
|
206
|
+
> 样板参考:`src/views/table/base/index.vue`、`src/views/form/moreForm/MultiFormDialog.vue`。
|
|
207
|
+
|
|
208
|
+
### Props / 插槽
|
|
209
|
+
|
|
210
|
+
| 项 | 说明 |
|
|
211
|
+
|---|---|
|
|
212
|
+
| `v-model` / `modelValue` | 显隐 |
|
|
213
|
+
| `title` | 标题文案(也可用 `#title` 插槽) |
|
|
214
|
+
| `width` | 默认 `'50%'` |
|
|
215
|
+
| `maxHeight` | 内容区滚动高度,默认 `500`(number 会拼 `px`) |
|
|
216
|
+
| `fullscreen` | 是否显示右上角全屏按钮,默认 `true` |
|
|
217
|
+
| 默认插槽 | 内容区(包在 scrollbar 内) |
|
|
218
|
+
| `#footer` | 有则渲染底部操作区 |
|
|
219
|
+
| `#title` | 自定义标题 |
|
|
220
|
+
| 其它 attrs | 透传给 `el-dialog`(组件内部会剔除 `fullscreen` / `title` / `maxHeight`) |
|
|
221
|
+
|
|
222
|
+
内置行为:`lock-scroll`、`draggable`、`destroy-on-close`、`close-on-click-modal=false`、自定义关闭/全屏图标(非默认 `show-close`)。
|
|
223
|
+
|
|
224
|
+
### 列表页表单弹窗(黄金样板)
|
|
225
|
+
|
|
226
|
+
```vue
|
|
227
|
+
<script setup lang="ts">
|
|
228
|
+
import type { FormInstance, FormRules } from "element-plus";
|
|
229
|
+
import ReDialog from "@/components/ReDialog";
|
|
230
|
+
import { message } from "@/utils/message";
|
|
231
|
+
|
|
232
|
+
defineOptions({ name: "CustomerDialog" });
|
|
233
|
+
|
|
234
|
+
const dialogVisible = ref(false);
|
|
235
|
+
const title = ref("");
|
|
236
|
+
const submitLoading = ref(false);
|
|
237
|
+
const formRef = ref<FormInstance>();
|
|
238
|
+
const formData = reactive({ name: "", status: 1 });
|
|
239
|
+
|
|
240
|
+
const rules: FormRules = {
|
|
241
|
+
name: [{ required: true, message: "请输入名称", trigger: "blur" }],
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
function openCreate() {
|
|
245
|
+
title.value = "新增客户";
|
|
246
|
+
Object.assign(formData, { name: "", status: 1 });
|
|
247
|
+
dialogVisible.value = true;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function openEdit(row: { name: string; status: number }) {
|
|
251
|
+
title.value = "编辑客户";
|
|
252
|
+
Object.assign(formData, row);
|
|
253
|
+
dialogVisible.value = true;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async function onSubmit() {
|
|
257
|
+
const ok = await formRef.value?.validate().catch(() => false);
|
|
258
|
+
if (!ok) return;
|
|
259
|
+
submitLoading.value = true;
|
|
260
|
+
try {
|
|
261
|
+
// await saveApi(formData)
|
|
262
|
+
message("保存成功", { type: "success" });
|
|
263
|
+
dialogVisible.value = false;
|
|
264
|
+
} finally {
|
|
265
|
+
submitLoading.value = false;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
defineExpose({ openCreate, openEdit });
|
|
270
|
+
</script>
|
|
271
|
+
|
|
272
|
+
<template>
|
|
273
|
+
<ReDialog v-model="dialogVisible" :title="title" width="560px" :max-height="420">
|
|
274
|
+
<el-form ref="formRef" :model="formData" :rules="rules" label-width="96px">
|
|
275
|
+
<el-form-item :label="$t('名称')" prop="name">
|
|
276
|
+
<el-input v-model="formData.name" />
|
|
277
|
+
</el-form-item>
|
|
278
|
+
<el-form-item :label="$t('状态')" prop="status">
|
|
279
|
+
<el-select v-model="formData.status" class="w-full">
|
|
280
|
+
<el-option :label="$t('启用')" :value="1" />
|
|
281
|
+
<el-option :label="$t('停用')" :value="0" />
|
|
282
|
+
</el-select>
|
|
283
|
+
</el-form-item>
|
|
284
|
+
</el-form>
|
|
285
|
+
<template #footer>
|
|
286
|
+
<el-button @click="dialogVisible = false">{{ $t("取 消") }}</el-button>
|
|
287
|
+
<el-button type="primary" :loading="submitLoading" @click="onSubmit">
|
|
288
|
+
{{ $t("确 定") }}
|
|
289
|
+
</el-button>
|
|
290
|
+
</template>
|
|
291
|
+
</ReDialog>
|
|
292
|
+
</template>
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### 大内容 / 多表单弹窗
|
|
296
|
+
|
|
297
|
+
```vue
|
|
298
|
+
<script setup lang="ts">
|
|
299
|
+
import { ReDialog } from "@/components/ReDialog";
|
|
300
|
+
|
|
301
|
+
const dialogVisible = ref(false);
|
|
128
302
|
</script>
|
|
303
|
+
|
|
304
|
+
<template>
|
|
305
|
+
<ReDialog
|
|
306
|
+
v-model="dialogVisible"
|
|
307
|
+
:title="$t('弹窗多表单')"
|
|
308
|
+
width="90%"
|
|
309
|
+
:max-height="600"
|
|
310
|
+
>
|
|
311
|
+
<!-- 内容区可嵌 ReAnchor + ReCollapsible;弹窗内锚点滚动容器传 scrollContent -->
|
|
312
|
+
<div class="min-h-400">...</div>
|
|
313
|
+
<template #footer>
|
|
314
|
+
<el-button @click="dialogVisible = false">{{ $t("取消") }}</el-button>
|
|
315
|
+
<el-button type="primary">{{ $t("确认保存") }}</el-button>
|
|
316
|
+
</template>
|
|
317
|
+
</ReDialog>
|
|
318
|
+
</template>
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### 约定
|
|
322
|
+
|
|
323
|
+
1. 业务弹窗优先 `ReDialog`,不要直接写裸 `el-dialog`。
|
|
324
|
+
2. 提交按钮必须有 `loading`,防止重复提交。
|
|
325
|
+
3. 需要二次确认删除等:用 `ElMessageBox.confirm` / `message` 封装,不必为确认框再套一层 `ReDialog`。
|
|
326
|
+
4. 弹窗内嵌锚点时指定 `scrollContent`(见上方 ReAnchor)。
|
|
327
|
+
|
|
328
|
+
---
|
|
329
|
+
|
|
330
|
+
## ReDialogResize 可拖拽缩放弹窗
|
|
331
|
+
|
|
332
|
+
> 落点:`src/components/ReDialogResize`。在 `ReDialog` 外包一层边缘拖拽改宽高。
|
|
333
|
+
> **何时用**:用户需要手动拉大/缩小内容区(复杂表单、预览、对照编辑)。普通 CRUD 弹窗用 `ReDialog` 即可。
|
|
334
|
+
|
|
335
|
+
### Props
|
|
336
|
+
|
|
337
|
+
| 项 | 说明 |
|
|
338
|
+
|---|---|
|
|
339
|
+
| `v-model` / `title` / `fullscreen` | 同 `ReDialog`,透传 |
|
|
340
|
+
| `initWidth` | 初始宽度(number,px),默认 `window.innerWidth / 2` |
|
|
341
|
+
| `initHeight` | 初始内容高度(number,px),默认 `500` |
|
|
342
|
+
| `minResizeWidth` / `minResizeHeight` | 缩放下限 |
|
|
343
|
+
|
|
344
|
+
```vue
|
|
345
|
+
<script setup lang="ts">
|
|
346
|
+
import ReDialogResize from "@/components/ReDialogResize";
|
|
347
|
+
|
|
348
|
+
const visible = ref(false);
|
|
349
|
+
</script>
|
|
350
|
+
|
|
351
|
+
<template>
|
|
352
|
+
<ReDialogResize
|
|
353
|
+
v-model="visible"
|
|
354
|
+
:title="$t('可缩放弹窗')"
|
|
355
|
+
:init-width="800"
|
|
356
|
+
:init-height="520"
|
|
357
|
+
:min-resize-width="560"
|
|
358
|
+
:min-resize-height="400"
|
|
359
|
+
>
|
|
360
|
+
<div>{{ $t("拖拽弹窗边缘可调整大小") }}</div>
|
|
361
|
+
<template #footer>
|
|
362
|
+
<el-button @click="visible = false">{{ $t("关闭") }}</el-button>
|
|
363
|
+
</template>
|
|
364
|
+
</ReDialogResize>
|
|
365
|
+
</template>
|
|
129
366
|
```
|
|
130
367
|
|
|
131
|
-
|
|
368
|
+
---
|
|
132
369
|
|
|
133
370
|
## 关键约定
|
|
134
371
|
|
|
135
|
-
1.
|
|
136
|
-
2.
|
|
137
|
-
3.
|
|
372
|
+
1. 业务弹窗用 `ReDialog`;要边缘缩放再用 `ReDialogResize`;勿业务页自研弹窗壳。
|
|
373
|
+
2. 简单下拉用 `el-select`;搜索+分页用 `ReSelectQuery`。
|
|
374
|
+
3. 树选用 `el-tree-select`;级联用 `ReCascader`。
|
|
375
|
+
4. 变更对比场景配合 `compare-config`(见 `data-compare`)。
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
# 知识图谱(relation-graph)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> 必须使用选型表中的 `relation-graph-vue3`,勿改用 D3 / vis.js 等同类库。按下列示例编写。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## 依赖(缺则先装)
|
|
6
|
+
|
|
7
|
+
| 包 | 版本 |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `relation-graph-vue3` | `2.2.11` |
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add relation-graph-vue3@2.2.11
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
先查 `package.json`;已存在则跳过安装。
|
|
6
16
|
|
|
7
17
|
## 页面结构
|
|
8
18
|
|
|
@@ -246,8 +256,3 @@ const legendConfig = ref([
|
|
|
246
256
|
3. 图谱容器必须有明确高度(使用 `calc(100vh - ...)` 计算)。
|
|
247
257
|
4. `setJsonData` 的回调中执行居中、缩放、高亮等初始化操作。
|
|
248
258
|
5. 节点自定义样式通过 `#node` 插槽,class 根据 `data` 字段动态绑定。
|
|
249
|
-
|
|
250
|
-
## 关联文件
|
|
251
|
-
|
|
252
|
-
- [src/views/graph/index.vue](file:///e:/work/vue3-web-temp/src/views/graph/index.vue)
|
|
253
|
-
- [src/api/graph.ts](file:///e:/work/vue3-web-temp/src/api/graph.ts)
|