jianghu-ui 1.0.1

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.
Files changed (112) hide show
  1. package/README.md +376 -0
  2. package/dist/jianghu-ui.css +2318 -0
  3. package/dist/jianghu-ui.js +2 -0
  4. package/dist/jianghu-ui.js.LICENSE.txt +1 -0
  5. package/package.json +56 -0
  6. package/src/Design.stories.mdx +195 -0
  7. package/src/Introduction.stories.mdx +148 -0
  8. package/src/components/JhAddressSelect/JhAddressSelect.md +250 -0
  9. package/src/components/JhAddressSelect/JhAddressSelect.stories.js +282 -0
  10. package/src/components/JhAddressSelect/JhAddressSelect.vue +261 -0
  11. package/src/components/JhCard/JhCard.md +246 -0
  12. package/src/components/JhCard/JhCard.stories.js +688 -0
  13. package/src/components/JhCard/JhCard.vue +604 -0
  14. package/src/components/JhCheckCard/JhCheckCard.md +245 -0
  15. package/src/components/JhCheckCard/JhCheckCard.stories.js +750 -0
  16. package/src/components/JhCheckCard/JhCheckCard.vue +476 -0
  17. package/src/components/JhConfirmDialog/JhConfirmDialog.md +70 -0
  18. package/src/components/JhConfirmDialog/JhConfirmDialog.stories.js +550 -0
  19. package/src/components/JhConfirmDialog/JhConfirmDialog.vue +181 -0
  20. package/src/components/JhDateRangePicker/JhDateRangePicker.md +56 -0
  21. package/src/components/JhDateRangePicker/JhDateRangePicker.stories.js +320 -0
  22. package/src/components/JhDateRangePicker/JhDateRangePicker.vue +307 -0
  23. package/src/components/JhDescriptions/JhDescriptions.md +724 -0
  24. package/src/components/JhDescriptions/JhDescriptions.stories.js +858 -0
  25. package/src/components/JhDescriptions/JhDescriptions.vue +933 -0
  26. package/src/components/JhDraggable/JhDraggable.md +66 -0
  27. package/src/components/JhDraggable/JhDraggable.stories.js +161 -0
  28. package/src/components/JhDraggable/JhDraggable.vue +254 -0
  29. package/src/components/JhDrawer/JhDrawer.md +68 -0
  30. package/src/components/JhDrawer/JhDrawer.stories.js +478 -0
  31. package/src/components/JhDrawer/JhDrawer.vue +281 -0
  32. package/src/components/JhDrawerForm/JhDrawerForm.md +69 -0
  33. package/src/components/JhDrawerForm/JhDrawerForm.stories.js +492 -0
  34. package/src/components/JhDrawerForm/JhDrawerForm.vue +297 -0
  35. package/src/components/JhEditableTable/JhEditableTable.md +507 -0
  36. package/src/components/JhEditableTable/JhEditableTable.stories.js +615 -0
  37. package/src/components/JhEditableTable/JhEditableTable.vue +685 -0
  38. package/src/components/JhFileInput/JhFileInput.md +56 -0
  39. package/src/components/JhFileInput/JhFileInput.stories.js +103 -0
  40. package/src/components/JhFileInput/JhFileInput.vue +253 -0
  41. package/src/components/JhForm/JhForm.md +676 -0
  42. package/src/components/JhForm/JhForm.stories.js +1375 -0
  43. package/src/components/JhForm/JhForm.vue +657 -0
  44. package/src/components/JhFormField/JhFormField.stories.js +217 -0
  45. package/src/components/JhFormField/JhFormField.vue +439 -0
  46. package/src/components/JhFormFields/JhFormFields.md +647 -0
  47. package/src/components/JhFormFields/JhFormFields.stories.js +922 -0
  48. package/src/components/JhFormFields/JhFormFields.vue +998 -0
  49. package/src/components/JhFormList/JhFormList.md +303 -0
  50. package/src/components/JhFormList/JhFormList.stories.js +661 -0
  51. package/src/components/JhFormList/JhFormList.vue +1127 -0
  52. package/src/components/JhJsonEditor/JhJsonEditor.md +54 -0
  53. package/src/components/JhJsonEditor/JhJsonEditor.stories.js +157 -0
  54. package/src/components/JhJsonEditor/JhJsonEditor.vue +178 -0
  55. package/src/components/JhLayout/JhLayout.md +580 -0
  56. package/src/components/JhLayout/JhLayout.stories.js +414 -0
  57. package/src/components/JhLayout/JhLayout.vue +387 -0
  58. package/src/components/JhList/JhList.md +441 -0
  59. package/src/components/JhList/JhList.stories.js +524 -0
  60. package/src/components/JhList/JhList.vue +571 -0
  61. package/src/components/JhMarkdownEditor/JhMarkdownEditor.md +56 -0
  62. package/src/components/JhMarkdownEditor/JhMarkdownEditor.stories.js +191 -0
  63. package/src/components/JhMarkdownEditor/JhMarkdownEditor.vue +188 -0
  64. package/src/components/JhMask/JhMask.md +62 -0
  65. package/src/components/JhMask/JhMask.stories.js +270 -0
  66. package/src/components/JhMask/JhMask.vue +123 -0
  67. package/src/components/JhMenu/JhMenu.md +85 -0
  68. package/src/components/JhMenu/JhMenu.stories.js +384 -0
  69. package/src/components/JhMenu/JhMenu.vue +545 -0
  70. package/src/components/JhModal/JhModal.md +68 -0
  71. package/src/components/JhModal/JhModal.stories.js +562 -0
  72. package/src/components/JhModal/JhModal.vue +235 -0
  73. package/src/components/JhModalForm/JhModalForm.md +69 -0
  74. package/src/components/JhModalForm/JhModalForm.stories.js +592 -0
  75. package/src/components/JhModalForm/JhModalForm.vue +298 -0
  76. package/src/components/JhPageContainer/JhPageContainer.md +409 -0
  77. package/src/components/JhPageContainer/JhPageContainer.stories.js +209 -0
  78. package/src/components/JhPageContainer/JhPageContainer.vue +72 -0
  79. package/src/components/JhQueryFilter/JhQueryFilter.md +77 -0
  80. package/src/components/JhQueryFilter/JhQueryFilter.stories.js +684 -0
  81. package/src/components/JhQueryFilter/JhQueryFilter.vue +429 -0
  82. package/src/components/JhScene/JhScene.md +64 -0
  83. package/src/components/JhScene/JhScene.stories.js +317 -0
  84. package/src/components/JhScene/JhScene.vue +376 -0
  85. package/src/components/JhStatisticCard/JhStatisticCard.md +363 -0
  86. package/src/components/JhStatisticCard/JhStatisticCard.stories.js +847 -0
  87. package/src/components/JhStatisticCard/JhStatisticCard.vue +459 -0
  88. package/src/components/JhStepsForm/JhStepsForm.md +666 -0
  89. package/src/components/JhStepsForm/JhStepsForm.stories.js +1224 -0
  90. package/src/components/JhStepsForm/JhStepsForm.vue +749 -0
  91. package/src/components/JhTable/JhTable.md +730 -0
  92. package/src/components/JhTable/JhTable.stories.js +1444 -0
  93. package/src/components/JhTable/JhTable.vue +2298 -0
  94. package/src/components/JhTableAttachment/JhTableAttachment.md +70 -0
  95. package/src/components/JhTableAttachment/JhTableAttachment.stories.js +198 -0
  96. package/src/components/JhTableAttachment/JhTableAttachment.vue +264 -0
  97. package/src/components/JhToast/JhToast.md +67 -0
  98. package/src/components/JhToast/JhToast.stories.js +386 -0
  99. package/src/components/JhToast/JhToast.vue +239 -0
  100. package/src/components/JhTreeSelect/JhTreeSelect.md +82 -0
  101. package/src/components/JhTreeSelect/JhTreeSelect.stories.js +391 -0
  102. package/src/components/JhTreeSelect/JhTreeSelect.vue +727 -0
  103. package/src/components/JhWaterMark/JhWaterMark.md +190 -0
  104. package/src/components/JhWaterMark/JhWaterMark.stories.js +675 -0
  105. package/src/components/JhWaterMark/JhWaterMark.vue +351 -0
  106. package/src/components/README.md +52 -0
  107. package/src/index.js +135 -0
  108. package/src/style/globalCSSJHV4.css +348 -0
  109. package/src/style/globalCSSVuetifyV4.css +637 -0
  110. package/src/style/storybook.css +4 -0
  111. package/src/tailwind.css +3 -0
  112. package/src/utils/vuetify.js +31 -0
@@ -0,0 +1,684 @@
1
+ import JhQueryFilter from './JhQueryFilter.vue';
2
+
3
+ export default {
4
+ title: '数据录入/JhQueryFilter - 筛选表单',
5
+ component: JhQueryFilter,
6
+ tags: ['autodocs'],
7
+ argTypes: {
8
+ fields: {
9
+ control: 'object',
10
+ description: '查询字段配置数组',
11
+ },
12
+ initialValues: {
13
+ control: 'object',
14
+ description: '初始查询数据',
15
+ },
16
+ collapsible: {
17
+ control: 'boolean',
18
+ description: '是否可折叠',
19
+ },
20
+ defaultCollapsed: {
21
+ control: 'boolean',
22
+ description: '默认是否折叠',
23
+ },
24
+ defaultVisibleCount: {
25
+ control: 'number',
26
+ description: '默认显示字段数量(折叠时)',
27
+ },
28
+ searchText: {
29
+ control: 'text',
30
+ description: '查询按钮文本',
31
+ },
32
+ resetText: {
33
+ control: 'text',
34
+ description: '重置按钮文本',
35
+ },
36
+ },
37
+ parameters: {
38
+ docs: {
39
+ description: {
40
+ component: `
41
+
42
+ 高级查询筛选组件,参考 Ant Design Pro QueryFilter 设计,支持字段配置化查询表单。
43
+
44
+ ## 功能特性
45
+
46
+ ### 1. 字段类型支持
47
+ - **text**: 文本输入框
48
+ - **number**: 数字输入框
49
+ - **select**: 下拉选择框(支持单选/多选)
50
+ - **autocomplete**: 自动完成
51
+ - **date**: 日期选择器
52
+ - **daterange**: 日期范围选择器
53
+ - **slot**: 自定义字段插槽
54
+
55
+ ### 2. 折叠/展开
56
+ - 默认显示前 3 个字段
57
+ - 超过设定数量自动显示展开按钮
58
+ - 支持自定义默认显示数量
59
+
60
+ ### 3. 查询操作
61
+ - 查询按钮:提交查询,自动过滤空值
62
+ - 重置按钮:清空所有字段并触发查询
63
+ - 支持回车键快速查询
64
+
65
+ ### 4. 响应式布局
66
+ - 自适应不同屏幕尺寸
67
+ - 支持自定义列宽配置
68
+
69
+ ## API
70
+
71
+ ### Props
72
+
73
+ | 参数 | 类型 | 默认值 | 说明 |
74
+ |-----|------|--------|------|
75
+ | fields | Array | [] | 字段配置数组 |
76
+ | initialValues | Object | {} | 初始查询数据 |
77
+ | collapsible | Boolean | true | 是否可折叠 |
78
+ | defaultCollapsed | Boolean | true | 默认是否折叠 |
79
+ | defaultVisibleCount | Number | 3 | 默认显示字段数量 |
80
+ | colSpan | Object | {...} | 列宽配置 |
81
+ | searchText | String | '查询' | 查询按钮文本 |
82
+ | resetText | String | '重置' | 重置按钮文本 |
83
+ | expandText | String | '展开' | 展开按钮文本 |
84
+ | collapseText | String | '收起' | 收起按钮文本 |
85
+
86
+ ### 字段配置 (Field Config)
87
+
88
+ \`\`\`javascript
89
+ {
90
+ key: 'fieldName', // 字段名称
91
+ label: '字段标签', // 字段标签
92
+ type: 'text', // 字段类型
93
+ placeholder: '请输入', // 占位符
94
+ defaultValue: '', // 默认值
95
+ options: [], // 选项(select/autocomplete)
96
+ cols: 12, // 列宽(xs)
97
+ sm: 12, // 列宽(sm)
98
+ md: 8, // 列宽(md)
99
+ lg: 6, // 列宽(lg)
100
+ disabled: false, // 是否禁用
101
+ realtime: false, // 是否实时查询
102
+ }
103
+ \`\`\`
104
+
105
+ ### Events
106
+
107
+ | 事件名 | 参数 | 说明 |
108
+ |-------|------|------|
109
+ | search | queryData | 查询事件,返回过滤后的查询数据 |
110
+ | reset | - | 重置事件 |
111
+ | field-change | { key, value, formData } | 字段变化事件 |
112
+ | collapse-change | collapsed | 折叠状态变化 |
113
+
114
+ ### Methods
115
+
116
+ | 方法名 | 参数 | 说明 |
117
+ |-------|------|------|
118
+ | getFormData | - | 获取表单数据 |
119
+ | setFieldsValue | values | 批量设置字段值 |
120
+ | setFieldValue | key, value | 设置单个字段值 |
121
+
122
+ ## 使用示例
123
+
124
+ \`\`\`vue
125
+ <template>
126
+ <jh-query-filter
127
+ :fields="queryFields"
128
+ :initial-values="initialValues"
129
+ @search="handleSearch"
130
+ @reset="handleReset"
131
+ />
132
+ </template>
133
+
134
+ <script>
135
+ export default {
136
+ data() {
137
+ return {
138
+ queryFields: [
139
+ {
140
+ key: 'keyword',
141
+ label: '关键词',
142
+ type: 'text',
143
+ placeholder: '请输入关键词',
144
+ },
145
+ {
146
+ key: 'status',
147
+ label: '状态',
148
+ type: 'select',
149
+ placeholder: '请选择状态',
150
+ options: [
151
+ { text: '全部', value: '' },
152
+ { text: '启用', value: 'active' },
153
+ { text: '禁用', value: 'inactive' },
154
+ ],
155
+ },
156
+ {
157
+ key: 'dateRange',
158
+ label: '日期范围',
159
+ type: 'daterange',
160
+ placeholder: '请选择日期',
161
+ },
162
+ ],
163
+ initialValues: {
164
+ status: '',
165
+ },
166
+ };
167
+ },
168
+ methods: {
169
+ handleSearch(queryData) {
170
+ console.log('查询参数:', queryData);
171
+ // 调用表格刷新等操作
172
+ },
173
+ handleReset() {
174
+ console.log('重置查询');
175
+ },
176
+ },
177
+ };
178
+ </script>
179
+ \`\`\`
180
+ `,
181
+ },
182
+ },
183
+ },
184
+ };
185
+
186
+ // 基础示例
187
+ export const 基础示例 = {
188
+ args: {
189
+ fields: [
190
+ {
191
+ key: 'keyword',
192
+ label: '关键词',
193
+ type: 'text',
194
+ placeholder: '请输入关键词',
195
+ },
196
+ {
197
+ key: 'status',
198
+ label: '状态',
199
+ type: 'select',
200
+ placeholder: '请选择状态',
201
+ options: [
202
+ { text: '全部', value: '' },
203
+ { text: '启用', value: 'active' },
204
+ { text: '禁用', value: 'inactive' },
205
+ ],
206
+ },
207
+ {
208
+ key: 'category',
209
+ label: '分类',
210
+ type: 'select',
211
+ placeholder: '请选择分类',
212
+ options: [
213
+ { text: '全部', value: '' },
214
+ { text: '技术', value: 'tech' },
215
+ { text: '产品', value: 'product' },
216
+ { text: '设计', value: 'design' },
217
+ ],
218
+ },
219
+ ],
220
+ initialValues: {},
221
+ collapsible: true,
222
+ defaultCollapsed: true,
223
+ defaultVisibleCount: 3,
224
+ },
225
+ render: (args) => ({
226
+ components: { JhQueryFilter },
227
+ data() {
228
+ return {
229
+ args,
230
+ queryData: {},
231
+ };
232
+ },
233
+ template: `
234
+ <div>
235
+ <jh-query-filter
236
+ v-bind="args"
237
+ @search="handleSearch"
238
+ @reset="handleReset"
239
+ />
240
+ <v-card class="mt-4" outlined>
241
+ <v-card-text>
242
+ <h4>查询参数:</h4>
243
+ <pre>{{ JSON.stringify(queryData, null, 2) }}</pre>
244
+ </v-card-text>
245
+ </v-card>
246
+ </div>
247
+ `,
248
+ methods: {
249
+ handleSearch(queryData) {
250
+ this.queryData = queryData;
251
+ console.log('查询参数:', queryData);
252
+ },
253
+ handleReset() {
254
+ console.log('重置查询');
255
+ },
256
+ },
257
+ }),
258
+ };
259
+
260
+ // 多字段折叠
261
+ export const 多字段折叠 = {
262
+ args: {
263
+ fields: [
264
+ {
265
+ key: 'keyword',
266
+ label: '关键词',
267
+ type: 'text',
268
+ placeholder: '请输入关键词',
269
+ },
270
+ {
271
+ key: 'status',
272
+ label: '状态',
273
+ type: 'select',
274
+ placeholder: '请选择状态',
275
+ options: [
276
+ { text: '全部', value: '' },
277
+ { text: '启用', value: 'active' },
278
+ { text: '禁用', value: 'inactive' },
279
+ ],
280
+ },
281
+ {
282
+ key: 'category',
283
+ label: '分类',
284
+ type: 'select',
285
+ placeholder: '请选择分类',
286
+ options: [
287
+ { text: '全部', value: '' },
288
+ { text: '技术', value: 'tech' },
289
+ { text: '产品', value: 'product' },
290
+ ],
291
+ },
292
+ {
293
+ key: 'author',
294
+ label: '作者',
295
+ type: 'text',
296
+ placeholder: '请输入作者',
297
+ },
298
+ {
299
+ key: 'priority',
300
+ label: '优先级',
301
+ type: 'select',
302
+ placeholder: '请选择优先级',
303
+ options: [
304
+ { text: '全部', value: '' },
305
+ { text: '高', value: 'high' },
306
+ { text: '中', value: 'medium' },
307
+ { text: '低', value: 'low' },
308
+ ],
309
+ },
310
+ {
311
+ key: 'tags',
312
+ label: '标签',
313
+ type: 'autocomplete',
314
+ placeholder: '请输入标签',
315
+ options: [
316
+ { text: 'Vue', value: 'vue' },
317
+ { text: 'React', value: 'react' },
318
+ { text: 'Angular', value: 'angular' },
319
+ ],
320
+ },
321
+ ],
322
+ initialValues: {},
323
+ collapsible: true,
324
+ defaultCollapsed: true,
325
+ defaultVisibleCount: 3,
326
+ },
327
+ render: 基础示例.render,
328
+ };
329
+
330
+ // 日期范围查询
331
+ export const 日期范围查询 = {
332
+ args: {
333
+ fields: [
334
+ {
335
+ key: 'keyword',
336
+ label: '关键词',
337
+ type: 'text',
338
+ placeholder: '请输入关键词',
339
+ },
340
+ {
341
+ key: 'status',
342
+ label: '状态',
343
+ type: 'select',
344
+ placeholder: '请选择状态',
345
+ options: [
346
+ { text: '全部', value: '' },
347
+ { text: '进行中', value: 'progress' },
348
+ { text: '已完成', value: 'completed' },
349
+ ],
350
+ },
351
+ {
352
+ key: 'date',
353
+ label: '日期',
354
+ type: 'date',
355
+ placeholder: '请选择日期',
356
+ },
357
+ {
358
+ key: 'dateRange',
359
+ label: '日期范围',
360
+ type: 'daterange',
361
+ placeholder: '请选择日期范围',
362
+ },
363
+ ],
364
+ initialValues: {},
365
+ collapsible: false,
366
+ },
367
+ render: 基础示例.render,
368
+ };
369
+
370
+ // 预设初始值
371
+ export const 预设初始值 = {
372
+ args: {
373
+ fields: [
374
+ {
375
+ key: 'keyword',
376
+ label: '关键词',
377
+ type: 'text',
378
+ placeholder: '请输入关键词',
379
+ },
380
+ {
381
+ key: 'status',
382
+ label: '状态',
383
+ type: 'select',
384
+ placeholder: '请选择状态',
385
+ options: [
386
+ { text: '全部', value: '' },
387
+ { text: '启用', value: 'active' },
388
+ { text: '禁用', value: 'inactive' },
389
+ ],
390
+ defaultValue: 'active',
391
+ },
392
+ {
393
+ key: 'category',
394
+ label: '分类',
395
+ type: 'select',
396
+ placeholder: '请选择分类',
397
+ options: [
398
+ { text: '全部', value: '' },
399
+ { text: '技术', value: 'tech' },
400
+ { text: '产品', value: 'product' },
401
+ ],
402
+ },
403
+ ],
404
+ initialValues: {
405
+ keyword: '搜索关键词',
406
+ status: 'active',
407
+ },
408
+ collapsible: false,
409
+ },
410
+ render: 基础示例.render,
411
+ };
412
+
413
+ // 自定义字段
414
+ export const 自定义字段 = {
415
+ args: {
416
+ fields: [
417
+ {
418
+ key: 'keyword',
419
+ label: '关键词',
420
+ type: 'text',
421
+ placeholder: '请输入关键词',
422
+ },
423
+ {
424
+ key: 'status',
425
+ label: '状态',
426
+ type: 'select',
427
+ placeholder: '请选择状态',
428
+ options: [
429
+ { text: '全部', value: '' },
430
+ { text: '启用', value: 'active' },
431
+ { text: '禁用', value: 'inactive' },
432
+ ],
433
+ },
434
+ {
435
+ key: 'customField',
436
+ label: '自定义字段',
437
+ type: 'slot',
438
+ },
439
+ ],
440
+ initialValues: {},
441
+ collapsible: false,
442
+ },
443
+ render: (args) => ({
444
+ components: { JhQueryFilter },
445
+ data() {
446
+ return {
447
+ args,
448
+ customValue: '',
449
+ queryData: {},
450
+ };
451
+ },
452
+ template: `
453
+ <div>
454
+ <jh-query-filter
455
+ v-bind="args"
456
+ @search="handleSearch"
457
+ @reset="handleReset"
458
+ >
459
+ <template #field-customField="{ updateField }">
460
+ <v-text-field
461
+ v-model="customValue"
462
+ placeholder="自定义字段插槽"
463
+ dense
464
+ filled
465
+ single-line
466
+ class="jh-v-input"
467
+ hide-details
468
+ @input="updateField('customField', $event)"
469
+ >
470
+ <template v-slot:append>
471
+ <v-icon small>mdi-magnify</v-icon>
472
+ </template>
473
+ </v-text-field>
474
+ </template>
475
+ </jh-query-filter>
476
+ <v-card class="mt-4" outlined>
477
+ <v-card-text>
478
+ <h4>查询参数:</h4>
479
+ <pre>{{ JSON.stringify(queryData, null, 2) }}</pre>
480
+ </v-card-text>
481
+ </v-card>
482
+ </div>
483
+ `,
484
+ methods: {
485
+ handleSearch(queryData) {
486
+ this.queryData = queryData;
487
+ console.log('查询参数:', queryData);
488
+ },
489
+ handleReset() {
490
+ this.customValue = '';
491
+ console.log('重置查询');
492
+ },
493
+ },
494
+ }),
495
+ };
496
+
497
+ // 自定义按钮
498
+ export const 自定义按钮 = {
499
+ args: {
500
+ fields: [
501
+ {
502
+ key: 'keyword',
503
+ label: '关键词',
504
+ type: 'text',
505
+ placeholder: '请输入关键词',
506
+ },
507
+ {
508
+ key: 'status',
509
+ label: '状态',
510
+ type: 'select',
511
+ placeholder: '请选择状态',
512
+ options: [
513
+ { text: '全部', value: '' },
514
+ { text: '启用', value: 'active' },
515
+ { text: '禁用', value: 'inactive' },
516
+ ],
517
+ },
518
+ ],
519
+ initialValues: {},
520
+ collapsible: false,
521
+ },
522
+ render: (args) => ({
523
+ components: { JhQueryFilter },
524
+ data() {
525
+ return {
526
+ args,
527
+ queryData: {},
528
+ };
529
+ },
530
+ template: `
531
+ <div>
532
+ <jh-query-filter
533
+ v-bind="args"
534
+ @search="handleSearch"
535
+ >
536
+ <template #buttons="{ formData, search, reset }">
537
+ <div class="d-flex align-center gap-2">
538
+ <v-btn
539
+ color="primary"
540
+ small
541
+ @click="search"
542
+ >
543
+ <v-icon left small>mdi-magnify</v-icon>
544
+ 搜索
545
+ </v-btn>
546
+ <v-btn
547
+ color="default"
548
+ small
549
+ text
550
+ @click="reset"
551
+ >
552
+ <v-icon left small>mdi-refresh</v-icon>
553
+ 清空
554
+ </v-btn>
555
+ <v-btn
556
+ color="success"
557
+ small
558
+ @click="handleExport"
559
+ >
560
+ <v-icon left small>mdi-download</v-icon>
561
+ 导出
562
+ </v-btn>
563
+ </div>
564
+ </template>
565
+ </jh-query-filter>
566
+ <v-card class="mt-4" outlined>
567
+ <v-card-text>
568
+ <h4>查询参数:</h4>
569
+ <pre>{{ JSON.stringify(queryData, null, 2) }}</pre>
570
+ </v-card-text>
571
+ </v-card>
572
+ </div>
573
+ `,
574
+ methods: {
575
+ handleSearch(queryData) {
576
+ this.queryData = queryData;
577
+ console.log('查询参数:', queryData);
578
+ },
579
+ handleExport() {
580
+ alert('导出数据');
581
+ },
582
+ },
583
+ }),
584
+ };
585
+
586
+ // 完整示例
587
+ export const 完整示例 = {
588
+ render: () => ({
589
+ components: { JhQueryFilter },
590
+ data() {
591
+ return {
592
+ queryFields: [
593
+ {
594
+ key: 'keyword',
595
+ label: '关键词',
596
+ type: 'text',
597
+ placeholder: '请输入用户名/邮箱',
598
+ },
599
+ {
600
+ key: 'status',
601
+ label: '状态',
602
+ type: 'select',
603
+ placeholder: '请选择状态',
604
+ options: [
605
+ { text: '全部', value: '' },
606
+ { text: '在职', value: 'active' },
607
+ { text: '离职', value: 'inactive' },
608
+ ],
609
+ },
610
+ {
611
+ key: 'department',
612
+ label: '部门',
613
+ type: 'select',
614
+ placeholder: '请选择部门',
615
+ options: [
616
+ { text: '全部', value: '' },
617
+ { text: '技术部', value: 'tech' },
618
+ { text: '产品部', value: 'product' },
619
+ { text: '设计部', value: 'design' },
620
+ ],
621
+ },
622
+ {
623
+ key: 'dateRange',
624
+ label: '入职时间',
625
+ type: 'daterange',
626
+ placeholder: '请选择日期范围',
627
+ },
628
+ ],
629
+ initialValues: {},
630
+ queryData: {},
631
+ tableData: [],
632
+ loading: false,
633
+ };
634
+ },
635
+ template: `
636
+ <div>
637
+ <v-card outlined>
638
+ <v-card-text>
639
+ <jh-query-filter
640
+ :fields="queryFields"
641
+ :initial-values="initialValues"
642
+ :loading="loading"
643
+ @search="handleSearch"
644
+ @reset="handleReset"
645
+ />
646
+ </v-card-text>
647
+ </v-card>
648
+
649
+ <v-card class="mt-4" outlined>
650
+ <v-card-text>
651
+ <h3>查询结果</h3>
652
+ <div class="mt-2">
653
+ <p><strong>当前查询条件:</strong></p>
654
+ <pre class="pa-2 grey lighten-4 rounded">{{ JSON.stringify(queryData, null, 2) }}</pre>
655
+ </div>
656
+ <div class="mt-4">
657
+ <p class="grey--text">在实际使用中,这里会显示 JhTable 组件,并根据查询条件刷新表格数据。</p>
658
+ <v-alert type="info" text dense>
659
+ 示例代码:&lt;jh-table :request="fetchData" /&gt;
660
+ </v-alert>
661
+ </div>
662
+ </v-card-text>
663
+ </v-card>
664
+ </div>
665
+ `,
666
+ methods: {
667
+ async handleSearch(queryData) {
668
+ this.loading = true;
669
+ this.queryData = queryData;
670
+ console.log('查询参数:', queryData);
671
+
672
+ // 模拟 API 请求
673
+ await new Promise(resolve => setTimeout(resolve, 1000));
674
+
675
+ this.loading = false;
676
+ console.log('查询完成');
677
+ },
678
+ handleReset() {
679
+ this.queryData = {};
680
+ console.log('重置查询');
681
+ },
682
+ },
683
+ }),
684
+ };