@tuoyuan/module-page-select 1.1.1 → 1.1.3

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 CHANGED
@@ -7,18 +7,21 @@ Vue 3 组件:用于选择业务模块、对应页面,编辑页面自带配
7
7
  - ✅ 模块与页面二级联动选择
8
8
  - ✅ 支持模块、页面数据缓存
9
9
  - ✅ 基于 JSON Schema 的动态表单渲染
10
- - ✅ 区分移动端(mobile)和 Web 端(external
11
- - ✅ 支持默认值回显
12
- - ✅ 自定义数据获取方法
13
- - ✅ 完整的 TypeScript 类型定义
10
+ - ✅ 区分移动端(mobile)和 Web 端(pc
11
+ - ✅ v-model 双向绑定支持
12
+ - ✅ 支持默认值回显与自动补全
13
+ - ✅ 完整的错误处理
14
+ - ✅ 支持横向/纵向/行内布局
15
+ - ✅ 灵活的确认按钮显示控制
16
+ - ✅ 自动触发 change 事件(无确认按钮模式)
14
17
 
15
18
  ## 安装
16
19
 
17
20
  ```bash
18
- npm install template-page-select
21
+ npm install @tuoyuan/template-page-select
19
22
  ```
20
23
 
21
- ## 使用
24
+ ## 基础使用
22
25
 
23
26
  ### 全局注册
24
27
 
@@ -37,10 +40,9 @@ app.mount('#app')
37
40
  ```vue
38
41
  <template>
39
42
  <ModulePageSelect
40
- type="mobile"
41
- :fetchModules="getModules"
42
- :fetchPages="getPages"
43
- @confirm="handleConfirm"
43
+ v-model="pageConfig"
44
+ @change="handleChange"
45
+ @error="handleError"
44
46
  />
45
47
  </template>
46
48
 
@@ -51,28 +53,17 @@ export default {
51
53
  components: {
52
54
  ModulePageSelect
53
55
  },
56
+ data() {
57
+ return {
58
+ pageConfig: {}
59
+ }
60
+ },
54
61
  methods: {
55
- async getModules() {
56
- // 返回模块列表
57
- const res = await fetch('/api/modules')
58
- return res.json()
59
- },
60
- async getPages(moduleId, pageType) {
61
- // 返回页面列表
62
- const res = await fetch(`/api/pages?moduleId=${moduleId}&type=${pageType}`)
63
- return res.json()
62
+ handleChange(config) {
63
+ console.log('页面配置已更新:', config)
64
64
  },
65
- handleConfirm(config) {
66
- console.log('选中配置:', config)
67
- // config 格式:
68
- // {
69
- // module_id: "66613bff9aa40000",
70
- // module_name: "操作日志",
71
- // page_id: "6663c53083e40000",
72
- // page_name: "操作日志",
73
- // page_type: 1,
74
- // configJson: {}
75
- // }
65
+ handleError(error) {
66
+ console.error('错误:', error)
76
67
  }
77
68
  }
78
69
  }
@@ -83,130 +74,190 @@ export default {
83
74
 
84
75
  ### Props
85
76
 
86
- | 参数 | 说明 | 类型 | 可选值 | 默认值 |
87
- |------|------|------|--------|--------|
88
- | type | 终端类型 | String | mobile / external | mobile |
89
- | defaultModuleId | 默认模块ID(用于回显) | String | - | '' |
90
- | defaultPageId | 默认页面ID(用于回显) | String | - | '' |
91
- | fetchModules | 自定义模块列表获取方法 | Function | - | null |
92
- | fetchPages | 自定义页面列表获取方法 | Function(moduleId, pageType) | - | null |
77
+ | 参数 | 说明 | 类型 | 默认值 |
78
+ |------|------|------|--------|
79
+ | modelValue | v-model 绑定的值 | Object | {} |
80
+ | moduleId | 模块ID(用于回显) | String | '' |
81
+ | pageId | 页面ID(用于回显) | String | '' |
82
+ | autoEcho | 是否在挂载时自动回显已有值 | Boolean | true |
83
+ | showCancelButton | 是否显示取消按钮 | Boolean | false |
84
+ | layout | 表单布局方式:`'vertical'` / `'horizontal'` / `'inline'` | String | 'vertical' |
85
+ | confirmButton | 是否显示确认按钮 | Boolean | true |
93
86
 
94
87
  ### Events
95
88
 
96
89
  | 事件名 | 说明 | 回调参数 |
97
90
  |--------|------|----------|
98
- | confirm | 确认选择时触发 | config: PageConfig |
91
+ | update:modelValue | v-model 值更新 | result: PageConfig |
92
+ | change | 选择确认后触发 | result: PageConfig |
93
+ | cancel | 取消选择时触发 | - |
99
94
  | error | 发生错误时触发 | { type: string, error: Error } |
100
95
 
101
- ### 数据格式
102
-
103
- #### 模块数据格式
96
+ ### 输出数据格式
104
97
 
105
98
  ```javascript
106
99
  {
107
- id: "66613bff9aa40000",
108
- name: "操作日志"
100
+ module_id: "66613bff9aa40000", // 模块ID
101
+ module_name: "操作日志", // 模块名称
102
+ page_id: "6663c53083e40000", // 页面ID
103
+ page_name: "操作日志", // 页面名称
104
+ type: "mobile", // 页面类型:mobile 或 pc
105
+ config: { // 页面配置(可选)
106
+ field1: "value1",
107
+ field2: 123
108
+ }
109
109
  }
110
110
  ```
111
111
 
112
- #### 页面数据格式
112
+ ## 使用示例
113
113
 
114
- ```javascript
115
- {
116
- id: "6663c53083e40000",
117
- name: "操作日志",
118
- type: 1, // 0: 移动端, 1: Web端
119
- options: {
120
- // JSON Schema 格式的配置
121
- properties: {
122
- wechatId: {
123
- type: "string",
124
- title: "微信ID",
125
- description: "请输入微信ID"
114
+ ### 示例 1:基础调用
115
+
116
+ ```vue
117
+ <template>
118
+ <div>
119
+ <ModulePageSelect v-model="selectedPage" @change="onPageChange" />
120
+ <div v-if="selectedPage.page_id">
121
+ <p>选中模块: {{ selectedPage.module_name }}</p>
122
+ <p>选中页面: {{ selectedPage.page_name }}</p>
123
+ </div>
124
+ </div>
125
+ </template>
126
+
127
+ <script>
128
+ import ModulePageSelect from 'template-page-select'
129
+
130
+ export default {
131
+ components: { ModulePageSelect },
132
+ data() {
133
+ return {
134
+ selectedPage: {}
135
+ }
136
+ },
137
+ methods: {
138
+ onPageChange(config) {
139
+ console.log('页面已更改:', config)
140
+ // 在这里可以保存配置、触发页面跳转等
141
+ }
142
+ }
143
+ }
144
+ </script>
145
+ ```
146
+
147
+ ### 示例 2:回显已有配置
148
+
149
+ ```vue
150
+ <template>
151
+ <ModulePageSelect
152
+ v-model="pageConfig"
153
+ :moduleId="form.moduleId"
154
+ :pageId="form.pageId"
155
+ @change="saveConfig"
156
+ />
157
+ </template>
158
+
159
+ <script>
160
+ export default {
161
+ data() {
162
+ return {
163
+ form: {
164
+ moduleId: '66613bff9aa40000',
165
+ pageId: '6663c53083e40000'
126
166
  },
127
- groupName: {
128
- type: "string",
129
- title: "业务分组"
167
+ pageConfig: {
168
+ module_id: '66613bff9aa40000',
169
+ module_name: '操作日志',
170
+ page_id: '6663c53083e40000',
171
+ page_name: '操作日志'
130
172
  }
131
173
  }
174
+ },
175
+ methods: {
176
+ saveConfig(config) {
177
+ console.log('配置已保存:', config)
178
+ }
132
179
  }
133
180
  }
181
+ </script>
134
182
  ```
135
183
 
136
- #### 输出配置格式
184
+ ### 示例 3:与表单集成
137
185
 
138
- ```javascript
139
- {
140
- module_id: "66613bff9aa40000",
141
- module_name: "操作日志",
142
- page_id: "6663c53083e40000",
143
- page_name: "操作日志",
144
- page_type: 1,
145
- configJson: {
146
- wechatId: "xxx",
147
- groupName: "xxx"
186
+ ```vue
187
+ <template>
188
+ <a-form @submit="handleSubmit">
189
+ <a-form-item label="页面选择">
190
+ <ModulePageSelect
191
+ v-model="form.page"
192
+ @error="handleError"
193
+ />
194
+ </a-form-item>
195
+ <a-form-item>
196
+ <a-button type="primary" html-type="submit">保存</a-button>
197
+ </a-form-item>
198
+ </a-form>
199
+ </template>
200
+
201
+ <script>
202
+ export default {
203
+ data() {
204
+ return {
205
+ form: {
206
+ page: {}
207
+ }
208
+ }
209
+ },
210
+ methods: {
211
+ handleSubmit() {
212
+ if (!this.form.page.page_id) {
213
+ this.$message.error('请选择页面')
214
+ return
215
+ }
216
+ console.log('提交表单:', this.form)
217
+ },
218
+ handleError(error) {
219
+ this.$message.error(`错误: ${error.type}`)
220
+ }
148
221
  }
149
222
  }
223
+ </script>
150
224
  ```
151
225
 
152
- ## 使用示例
153
-
154
- ### 示例 1:基础通用调用
226
+ ### 示例 4:横向布局
155
227
 
156
228
  ```vue
157
229
  <template>
158
230
  <ModulePageSelect
159
- type="mobile"
160
- :fetchModules="fetchModules"
161
- :fetchPages="fetchPages"
162
- @confirm="handlePageConfirm"
231
+ v-model="pageConfig"
232
+ layout="horizontal"
233
+ @change="handleChange"
163
234
  />
164
235
  </template>
165
236
 
166
237
  <script>
167
238
  export default {
239
+ data() {
240
+ return {
241
+ pageConfig: {}
242
+ }
243
+ },
168
244
  methods: {
169
- async fetchModules() {
170
- // 实现模块获取逻辑
171
- return [
172
- { id: '1', name: '模块1' },
173
- { id: '2', name: '模块2' }
174
- ]
175
- },
176
- async fetchPages(moduleId, pageType) {
177
- // 实现页面获取逻辑
178
- return [
179
- {
180
- id: '1',
181
- name: '页面1',
182
- type: pageType,
183
- options: {
184
- properties: {
185
- field1: { type: 'string', title: '字段1' }
186
- }
187
- }
188
- }
189
- ]
190
- },
191
- handlePageConfirm(pageConfig) {
192
- console.log('选中页面配置', pageConfig)
245
+ handleChange(config) {
246
+ console.log('页面配置:', config)
193
247
  }
194
248
  }
195
249
  }
196
250
  </script>
197
251
  ```
198
252
 
199
- ### 示例 2:回显已有页面数据
253
+ ### 示例 5:隐藏确认按钮,选择后自动触发
200
254
 
201
255
  ```vue
202
256
  <template>
203
257
  <ModulePageSelect
204
- type="external"
205
- :defaultModuleId="form.moduleId"
206
- :defaultPageId="form.pageId"
207
- :fetchModules="fetchModules"
208
- :fetchPages="fetchPages"
209
- @confirm="savePageInfo"
258
+ v-model="pageConfig"
259
+ :confirm-button="false"
260
+ @change="handleAutoChange"
210
261
  />
211
262
  </template>
212
263
 
@@ -214,54 +265,228 @@ export default {
214
265
  export default {
215
266
  data() {
216
267
  return {
217
- form: {
218
- moduleId: '66613bff9aa40000',
219
- pageId: '6663c53083e40000'
220
- }
268
+ pageConfig: {}
269
+ }
270
+ },
271
+ methods {
272
+ handleAutoChange(config) {
273
+ console.log('自动触发 change 事件:', config)
274
+ // 不需要点击确认按钮,选择页面后自动触发
275
+ }
276
+ }
277
+ }
278
+ </script>
279
+ ```
280
+
281
+ ### 示例 6:行内布局 + 无确认按钮
282
+
283
+ ```vue
284
+ <template>
285
+ <div class="page-selector-wrapper">
286
+ <span>快速选择:</span>
287
+ <ModulePageSelect
288
+ v-model="pageConfig"
289
+ layout="inline"
290
+ :confirm-button="false"
291
+ @change="handleQuickSelect"
292
+ />
293
+ </div>
294
+ </template>
295
+
296
+ <script>
297
+ export default {
298
+ data() {
299
+ return {
300
+ pageConfig: {}
221
301
  }
222
302
  },
223
303
  methods: {
224
- async fetchModules() {
225
- // 获取模块列表
226
- },
227
- async fetchPages(moduleId, pageType) {
228
- // 获取页面列表
229
- },
230
- savePageInfo(data) {
231
- // 存储选中的模块、页面及配置
232
- this.form.moduleId = data.module_id
233
- this.form.pageId = data.page_id
234
- console.log('配置数据:', data.configJson)
304
+ handleQuickSelect(config) {
305
+ console.log('快速选择:', config)
306
+ // 适用于工具栏、筛选条等场景
307
+ this.$router.push({
308
+ name: 'PagePreview',
309
+ query: {
310
+ moduleId: config.module_id,
311
+ pageId: config.page_id
312
+ }
313
+ })
235
314
  }
236
315
  }
237
316
  }
238
317
  </script>
239
318
  ```
240
319
 
241
- ## 核心功能说明
320
+ ## 数据接口说明
321
+
322
+ ### 模块列表接口
323
+
324
+ 默认调用 `/api/assembly-center.extend_module.list`
325
+
326
+ **请求参数:**
327
+ ```javascript
328
+ {
329
+ page_no: 1,
330
+ page_size: 1000
331
+ }
332
+ ```
333
+
334
+ **响应格式:**
335
+ ```javascript
336
+ {
337
+ data: {
338
+ list: [
339
+ { id: "1", name: "模块1" },
340
+ { id: "2", name: "模块2" }
341
+ ]
342
+ }
343
+ }
344
+ ```
345
+
346
+ ### 页面列表接口
242
347
 
243
- ### 1. 模块与页面加载逻辑
348
+ 默认调用 `/api/assembly-center.extend_module.page_list`
244
349
 
245
- - 初始化优先读取模块缓存,无缓存再请求接口拉取模块列表
246
- - 切换模块清空旧页面数据,重新获取当前模块下所有页面并缓存
247
- - 选中页面:加载页面配置
248
- - 有配置(非空对象)→ 渲染动态表单
249
- - 无配置(null/{})→ 不展示表单区域
350
+ **请求参数:**
351
+ ```javascript
352
+ {
353
+ module_id: "xxx", // 可选,不传时返回全部
354
+ type: 2, // 1: pc, 2: mobile
355
+ page_no: 1,
356
+ page_size: 1000
357
+ }
358
+ ```
359
+
360
+ **响应格式:**
361
+ ```javascript
362
+ {
363
+ data: {
364
+ list: [
365
+ {
366
+ id: "1",
367
+ name: "页面1",
368
+ module_id: "1",
369
+ options: {
370
+ // JSON Schema 格式配置
371
+ properties: {
372
+ field1: {
373
+ type: "string",
374
+ title: "字段1",
375
+ description: "字段1说明"
376
+ }
377
+ }
378
+ }
379
+ }
380
+ ]
381
+ }
382
+ }
383
+ ```
250
384
 
251
- ### 2. 动态表单渲染
385
+ ## 页面配置 Schema
252
386
 
253
387
  组件支持基于 JSON Schema 的动态表单渲染,支持以下字段类型:
254
388
 
255
- - `string` → 文本输入框
256
- - `number` / `integer` → 数字输入框
257
- - `enum` → 下拉选择框
389
+ ### 基础类型
390
+
391
+ ```javascript
392
+ {
393
+ properties: {
394
+ // 文本输入
395
+ username: {
396
+ type: "string",
397
+ title: "用户名",
398
+ description: "请输入用户名"
399
+ },
400
+ // 数字输入
401
+ age: {
402
+ type: "number",
403
+ title: "年龄",
404
+ default: 18
405
+ },
406
+ // 下拉选择
407
+ gender: {
408
+ type: "string",
409
+ title: "性别",
410
+ enum: ["male", "female"],
411
+ enumDescriptions: ["男", "女"]
412
+ }
413
+ }
414
+ }
415
+ ```
416
+
417
+ ### 嵌套对象
418
+
419
+ ```javascript
420
+ {
421
+ properties: {
422
+ user: {
423
+ type: "object",
424
+ title: "用户信息",
425
+ properties: {
426
+ name: {
427
+ type: "string",
428
+ title: "姓名"
429
+ },
430
+ email: {
431
+ type: "string",
432
+ title: "邮箱"
433
+ }
434
+ }
435
+ }
436
+ }
437
+ }
438
+ ```
439
+
440
+ ### 数组类型
441
+
442
+ ```javascript
443
+ {
444
+ properties: {
445
+ tags: {
446
+ type: "array",
447
+ title: "标签列表",
448
+ items: {
449
+ type: "object",
450
+ properties: {
451
+ name: { type: "string", title: "标签名" },
452
+ value: { type: "string", title: "标签值" }
453
+ }
454
+ }
455
+ }
456
+ }
457
+ }
458
+ ```
459
+
460
+ ## 核心逻辑说明
461
+
462
+ ### 1. 数据加载流程
463
+
464
+ 1. **初始化**:组件挂载时检查 `autoEcho`
465
+ - 若为 true,自动回显 `modelValue` 或 `moduleId`/`pageId` 对应的数据
466
+ - 若为 false,等待用户交互
467
+
468
+ 2. **模块加载**:用户 focus 模块下拉框时
469
+ - 优先返回缓存数据
470
+ - 无缓存时调用接口 `/api/assembly-center.extend_module.list`
471
+
472
+ 3. **页面加载**:用户选择模块或 focus 页面下拉框时
473
+ - 优先返回该模块的缓存数据
474
+ - 无缓存时调用接口 `/api/assembly-center.extend_module.page_list`
475
+
476
+ ### 2. 事件触发时机
477
+
478
+ | 事件 | 触发时机 |
479
+ |------|--------|
480
+ | `change` | 用户点击确认按钮后 |
481
+ | `error` | 接口请求失败时 |
482
+ | `update:modelValue` | 与 `change` 同时触发 |
258
483
 
259
- ### 3. 配置使用规则
484
+ ### 3. 页面方向选择
260
485
 
261
- 1. 前端用 `page_id` 绑定页面路由
262
- 2. 后端解析只依赖 `module_id` 和 `page_id`,名称字段仅做展示
263
- 3. 页面初始化读取 `configJson`,回填表单
264
- 4. 根据 `page_type` 走不同端逻辑(0: 移动端, 1: Web端)
486
+ - **竖向(portrait)**:默认选项,适合移动端竖屏显示
487
+ - **横向(landscape)**:适合移动端横屏显示
488
+
489
+ 选中的方向会包含在返回的 `orientation` 字段中
265
490
 
266
491
  ## 开发
267
492
 
@@ -279,6 +504,27 @@ npm run build:lib
279
504
  npm run lint
280
505
  ```
281
506
 
507
+ ## 常见问题
508
+
509
+ ### Q: 如何自定义数据接口?
510
+
511
+ A: 组件默认调用内置的两个接口。如需自定义,可以:
512
+
513
+ 1. 在外部获取数据后通过 `modelValue` prop 传入
514
+ 2. 或修改接口地址在 `fetchModulesFromAPI` 和 `fetchPagesFromAPI` 方法中
515
+
516
+ ### Q: 页面配置为空时会怎样?
517
+
518
+ A: 若页面 `options` 为空对象或不存在,组件不会展示配置表单,直接显示确认按钮。
519
+
520
+ ### Q: 如何禁用确认按钮?
521
+
522
+ A: 必须同时选择模块和页面,确认按钮才会启用。未选择时按钮自动禁用。
523
+
524
+ ### Q: 支持国际化吗?
525
+
526
+ A: 当前版本不支持国际化,所有文本为硬编码。可在后续版本中扩展。
527
+
282
528
  ## License
283
529
 
284
- MIT
530
+ MIT