jianghu-ui 1.0.6 → 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.
Files changed (49) hide show
  1. package/dist/jianghu-ui.css +195 -132
  2. package/dist/jianghu-ui.js +1 -1
  3. package/package.json +1 -1
  4. package/src/components/JhDrawer/JhDrawer.stories.js +6 -6
  5. package/src/components/JhDrawer/JhDrawer.vue +7 -1
  6. package/src/components/JhDrawerForm/JhDrawerForm.stories.js +161 -0
  7. package/src/components/JhDrawerForm/JhDrawerForm.vue +1 -1
  8. package/src/components/JhForm/JhForm.stories.js +114 -95
  9. package/src/components/JhForm/JhForm.vue +896 -205
  10. package/src/components/JhFormFields/JhFormFields.vue +42 -16
  11. package/src/components/JhModal/JhModal.stories.js +6 -6
  12. package/src/components/JhModal/JhModal.vue +1 -1
  13. package/src/components/JhModalForm/JhModalForm.vue +1 -1
  14. package/src/components/JhTable/JhTable.stories.js +134 -167
  15. package/src/components/JhTable/JhTable.vue +83 -23
  16. package/src/style/globalCSSVuetifyV4.css +1 -2
  17. package/src/components/JhAddressSelect/JhAddressSelect.md +0 -267
  18. package/src/components/JhCard/JhCard.md +0 -246
  19. package/src/components/JhCheckCard/JhCheckCard.md +0 -245
  20. package/src/components/JhConfirmDialog/JhConfirmDialog.md +0 -70
  21. package/src/components/JhDateRangePicker/JhDateRangePicker.md +0 -56
  22. package/src/components/JhDescriptions/JhDescriptions.md +0 -724
  23. package/src/components/JhDraggable/JhDraggable.md +0 -66
  24. package/src/components/JhDrawer/JhDrawer.md +0 -68
  25. package/src/components/JhDrawerForm/JhDrawerForm.md +0 -69
  26. package/src/components/JhEditableTable/JhEditableTable.md +0 -507
  27. package/src/components/JhFileInput/JhFileInput.md +0 -56
  28. package/src/components/JhForm/JhForm.md +0 -676
  29. package/src/components/JhFormFields/JhFormFields.md +0 -647
  30. package/src/components/JhFormList/JhFormList.md +0 -303
  31. package/src/components/JhJsonEditor/JhJsonEditor.md +0 -54
  32. package/src/components/JhLayout/JhLayout.md +0 -580
  33. package/src/components/JhList/JhList.md +0 -441
  34. package/src/components/JhMarkdownEditor/JhMarkdownEditor.md +0 -56
  35. package/src/components/JhMask/JhMask.md +0 -62
  36. package/src/components/JhMenu/JhMenu.md +0 -85
  37. package/src/components/JhModal/JhModal.md +0 -68
  38. package/src/components/JhModalForm/JhModalForm.md +0 -69
  39. package/src/components/JhPageContainer/JhPageContainer.md +0 -409
  40. package/src/components/JhQueryFilter/JhQueryFilter.md +0 -77
  41. package/src/components/JhScene/JhScene.md +0 -64
  42. package/src/components/JhStatisticCard/JhStatisticCard.md +0 -363
  43. package/src/components/JhStepsForm/JhStepsForm.md +0 -666
  44. package/src/components/JhTable/JhTable.md +0 -730
  45. package/src/components/JhTableAttachment/JhTableAttachment.md +0 -70
  46. package/src/components/JhToast/JhToast.md +0 -67
  47. package/src/components/JhTreeSelect/JhTreeSelect.md +0 -82
  48. package/src/components/JhWaterMark/JhWaterMark.md +0 -190
  49. package/src/components/README.md +0 -52
@@ -65,8 +65,9 @@
65
65
  />
66
66
  <template v-else>
67
67
  <v-icon small class="mr-2" color="primary">mdi-checkbox-marked-circle</v-icon>
68
- <span>已选择 <strong class="primary--text">{{ selectedItems.length }}</strong> 项</span>
69
- <v-btn text x-small class="ml-2" @click="clearSelection">清空</v-btn>
68
+ <div>已选择 <strong class="primary--text">{{ selectedItems.length }}</strong> 项</div>
69
+ <v-spacer></v-spacer>
70
+ <a text x-small class="ml-2" @click="clearSelection">清空</a>
70
71
  </template>
71
72
  </div>
72
73
  <div v-if="hasAlertActionsContent" class="jh-pro-table-alert-actions">
@@ -254,7 +255,7 @@
254
255
  :show-select="showSelectComputed"
255
256
  :single-select="singleSelectComputed"
256
257
  :value="selectedItems"
257
- :item-key="rowKey"
258
+ :item-key="computedRowKey"
258
259
  :dense="tableDense"
259
260
  :multi-sort="multiSort"
260
261
  :must-sort="mustSort"
@@ -277,7 +278,7 @@
277
278
  <slot :name="`header.${header.value}`" :header="h">{{ h.text || h.title }}</slot>
278
279
  </template>
279
280
 
280
- <!-- 自定义列插槽 -->
281
+ <!-- 自定义列插槽 (透传 item.* 并在没有时回退到默认渲染) -->
281
282
  <template
282
283
  v-for="header in visibleHeaders"
283
284
  v-slot:[`item.${header.value}`]="{ item, value, index }"
@@ -383,10 +384,10 @@
383
384
 
384
385
  <!-- 普通列 -->
385
386
  <template v-else>
386
- <!-- 自定义插槽 -->
387
- <slot v-if="header.slot || $scopedSlots[`item.${header.value}`]" :name="`item.${header.value}`" :item="item" :value="value"></slot>
387
+ <!-- 自定义插槽 (透传 item.[value]) -->
388
+ <slot v-if="header.slot || $scopedSlots[`item.${header.value}`]" :name="`item.${header.value}`" :item="item" :value="value" :index="index"></slot>
388
389
 
389
- <!-- 列配置渲染 -->
390
+ <!-- 列配置渲染 (没有自定义插槽时) -->
390
391
  <div v-else class="jh-table-schema-cell d-flex align-center flex-wrap">
391
392
  <!-- 状态标签 -->
392
393
  <template v-if="header.valueType === 'status'">
@@ -486,8 +487,13 @@
486
487
  </template>
487
488
  </template>
488
489
 
490
+ <!-- 透传所有其他插槽 (v-data-table 的原生插槽,排除已处理的) -->
491
+ <template v-for="slotName in passthroughSlots" v-slot:[slotName]="slotProps">
492
+ <slot :name="slotName" v-bind="slotProps"></slot>
493
+ </template>
494
+
489
495
  <!-- 加载中 -->
490
- <template v-slot:loading>
496
+ <template v-if="!$scopedSlots.loading" v-slot:loading>
491
497
  <div class="jh-no-data pa-6">
492
498
  <v-progress-circular indeterminate color="primary"></v-progress-circular>
493
499
  <div class="mt-2">数据加载中...</div>
@@ -495,7 +501,7 @@
495
501
  </template>
496
502
 
497
503
  <!-- 无数据 -->
498
- <template v-slot:no-data>
504
+ <template v-if="!$scopedSlots['no-data']" v-slot:no-data>
499
505
  <div class="jh-no-data pa-6">
500
506
  <v-icon large color="grey lighten-1">mdi-inbox-outline</v-icon>
501
507
  <div class="mt-2 text-body-2 grey--text">暂无数据</div>
@@ -503,7 +509,7 @@
503
509
  </template>
504
510
 
505
511
  <!-- 无结果 -->
506
- <template v-slot:no-results>
512
+ <template v-if="!$scopedSlots['no-results']" v-slot:no-results>
507
513
  <div class="jh-no-data pa-6">
508
514
  <v-icon large color="grey lighten-1">mdi-magnify</v-icon>
509
515
  <div class="mt-2 text-body-2 grey--text">未找到匹配的数据</div>
@@ -511,7 +517,7 @@
511
517
  </template>
512
518
 
513
519
  <!-- 分页文本 -->
514
- <template v-slot:[`footer.page-text`]="pagination">
520
+ <template v-if="!$scopedSlots['footer.page-text']" v-slot:[`footer.page-text`]="pagination">
515
521
  <span>{{ pagination.pageStart }}-{{ pagination.pageStop }}</span>
516
522
  <span class="ml-1">共{{ pagination.itemsLength }}条</span>
517
523
  </template>
@@ -808,11 +814,16 @@ export default {
808
814
  },
809
815
  rowKey: {
810
816
  type: String,
811
- default: 'id'
817
+ default: undefined
818
+ },
819
+ // 别名,兼容 v-data-table
820
+ itemKey: {
821
+ type: String,
822
+ default: undefined
812
823
  },
813
824
  size: {
814
825
  type: String,
815
- default: 'default', // default / medium / compact
826
+ default: 'medium', // default / medium / compact
816
827
  validator: (v) => ['default', 'medium', 'compact'].includes(v)
817
828
  },
818
829
  footerProps: {
@@ -882,13 +893,15 @@ export default {
882
893
  internalSortBy: this.normalizeSortBy(this.sortBy),
883
894
  internalSortDesc: this.normalizeSortDesc(this.sortDesc),
884
895
  sortChangeTimer: null,
885
- hasAppliedDefaultRowSelection: false
896
+ hasAppliedDefaultRowSelection: false,
897
+ // 最终使用的 item-key
898
+ computedRowKey: this.rowKey || this.itemKey || this.$attrs['item-key'] || 'id'
886
899
  };
887
900
  },
888
901
  computed: {
889
902
  // 选中的行 keys
890
903
  selectedRowKeys() {
891
- return this.selectedItems.map(item => item[this.rowKey]);
904
+ return this.selectedItems.map(item => item[this.computedRowKey]);
892
905
  },
893
906
 
894
907
  tableAlertScope() {
@@ -1013,6 +1026,24 @@ export default {
1013
1026
  customHeaderSlots() {
1014
1027
  return this.internalColumns.filter(h => this.$scopedSlots[`header.${h.value}`]);
1015
1028
  },
1029
+ // 需要透传的原生插槽
1030
+ passthroughSlots() {
1031
+ const handledSlots = [
1032
+ 'loading', 'no-data', 'no-results', 'footer.page-text',
1033
+ 'toolbar-actions', 'toolbar-extra', 'header-title', 'table-extra', 'alert', 'alert-actions'
1034
+ ];
1035
+ return Object.keys(this.$scopedSlots).filter(name => {
1036
+ // 排除已处理的 item.* 和 header.*
1037
+ if (name.startsWith('item.') || name.startsWith('header.')) {
1038
+ return false;
1039
+ }
1040
+ // 排除筛选字段插槽
1041
+ if (name.startsWith('filter-field-')) {
1042
+ return false;
1043
+ }
1044
+ return !handledSlots.includes(name);
1045
+ });
1046
+ },
1016
1047
  // 表格样式类
1017
1048
  tableClassComputed() {
1018
1049
  return [
@@ -1098,7 +1129,7 @@ export default {
1098
1129
  'filterSearchText', 'filterResetText', 'showCreateButton', 'showUpdateAction',
1099
1130
  'showDeleteAction', 'actionColumn', 'columnsState', 'pagination',
1100
1131
  'itemsPerPage', 'rowSelection', 'tableAlertRender', 'tableAlertOptionRender',
1101
- 'showSelect', 'singleSelect', 'rowKey', 'size', 'footerProps',
1132
+ 'showSelect', 'singleSelect', 'rowKey', 'itemKey', 'size', 'footerProps',
1102
1133
  'tableClass', 'polling', 'debounceTime', 'dataTableProps'
1103
1134
  ];
1104
1135
 
@@ -1215,6 +1246,12 @@ export default {
1215
1246
  this.$nextTick(() => this.applySelectionState());
1216
1247
  }
1217
1248
  },
1249
+ rowKey(val) {
1250
+ this.computedRowKey = val || this.itemKey || this.$attrs['item-key'] || 'id';
1251
+ },
1252
+ itemKey(val) {
1253
+ this.computedRowKey = this.rowKey || val || this.$attrs['item-key'] || 'id';
1254
+ },
1218
1255
  actionColumn: {
1219
1256
  handler() {
1220
1257
  this.initColumns(this.headers);
@@ -1618,7 +1655,7 @@ export default {
1618
1655
  handleSelectionChange(selectedItems) {
1619
1656
  this.selectedItems = selectedItems;
1620
1657
  const payload = {
1621
- selectedRowKeys: selectedItems.map(item => item[this.rowKey]),
1658
+ selectedRowKeys: selectedItems.map(item => item[this.computedRowKey]),
1622
1659
  selectedRows: selectedItems
1623
1660
  };
1624
1661
  this.$emit('selection-change', payload);
@@ -1824,6 +1861,10 @@ export default {
1824
1861
  if (!label) return '';
1825
1862
  return type === 'select' ? `请选择${label}` : `请输入${label}`;
1826
1863
  },
1864
+ // 获取原生 v-data-table 实例
1865
+ getVDataTable() {
1866
+ return this.$refs.dataTable;
1867
+ },
1827
1868
  // 重新加载数据(服务端分页)
1828
1869
  async reload() {
1829
1870
  if (!this.request) return;
@@ -2042,7 +2083,7 @@ export default {
2042
2083
  syncSelectionByKeys(keys) {
2043
2084
  if (!Array.isArray(keys)) return;
2044
2085
  const keySet = new Set(keys);
2045
- const matched = this.currentItems.filter(item => keySet.has(item[this.rowKey]));
2086
+ const matched = this.currentItems.filter(item => keySet.has(item[this.computedRowKey]));
2046
2087
  this.selectedItems = matched;
2047
2088
  this.$emit('input', matched);
2048
2089
  },
@@ -2050,7 +2091,7 @@ export default {
2050
2091
  if (this.hasAppliedDefaultRowSelection) return;
2051
2092
  if (!this.rowSelection || !Array.isArray(this.rowSelection.defaultSelectedRowKeys)) return;
2052
2093
  const keySet = new Set(this.rowSelection.defaultSelectedRowKeys);
2053
- const matched = this.currentItems.filter(item => keySet.has(item[this.rowKey]));
2094
+ const matched = this.currentItems.filter(item => keySet.has(item[this.computedRowKey]));
2054
2095
  if (matched.length) {
2055
2096
  this.selectedItems = matched;
2056
2097
  this.$emit('input', matched);
@@ -2081,7 +2122,7 @@ export default {
2081
2122
  display: flex;
2082
2123
  align-items: center;
2083
2124
  justify-content: space-between;
2084
- padding: 16px 24px;
2125
+ padding: 16px 0;
2085
2126
  border-bottom: 1px solid #f0f0f0;
2086
2127
  min-height: 64px;
2087
2128
  }
@@ -2099,7 +2140,10 @@ export default {
2099
2140
  height: 40px;
2100
2141
  }
2101
2142
  .jh-pro-table ::v-deep .jh-table-medium.v-data-table > .v-data-table__wrapper > table > tbody > tr > td {
2102
- height: 40px;
2143
+ min-height: 40px;
2144
+ height: 40px;
2145
+ color: #333C44;
2146
+ font-size: .8125rem;
2103
2147
  }
2104
2148
 
2105
2149
 
@@ -2133,14 +2177,14 @@ export default {
2133
2177
  align-items: center;
2134
2178
  justify-content: space-between;
2135
2179
  padding: 12px 24px;
2136
- background: #e6f7ff;
2137
- border: 1px solid #91d5ff;
2180
+ background: #fbfbfb;
2138
2181
  border-radius: 4px;
2139
2182
  margin: 16px 0 0;
2140
2183
  }
2141
2184
 
2142
2185
  .jh-pro-table-alert-info {
2143
2186
  display: flex;
2187
+ flex: 1;
2144
2188
  align-items: center;
2145
2189
  font-size: 14px;
2146
2190
  color: rgba(0, 0, 0, 0.65);
@@ -2155,6 +2199,7 @@ export default {
2155
2199
  /* 工具栏 */
2156
2200
  .jh-pro-table-toolbar {
2157
2201
  padding: 16px 0 !important;
2202
+ flex: inherit;
2158
2203
  }
2159
2204
 
2160
2205
  /* 表格额外内容区 */
@@ -2225,6 +2270,7 @@ export default {
2225
2270
  .jh-table-default >>> .v-data-table > .v-data-table__wrapper > table > thead > tr > th {
2226
2271
  height: 48px !important;
2227
2272
  padding: 0 16px !important;
2273
+
2228
2274
  }
2229
2275
 
2230
2276
  .jh-table-medium >>> .v-data-table > .v-data-table__wrapper > table > tbody > tr > td,
@@ -2338,6 +2384,20 @@ export default {
2338
2384
  cursor: pointer;
2339
2385
  }
2340
2386
 
2387
+ /* 表格行选中样式 */
2388
+ .jh-pro-table ::v-deep .v-data-table > .v-data-table__wrapper > table > tbody > tr.v-data-table__selected {
2389
+ background-color: #E6F7FF !important;
2390
+ }
2391
+
2392
+ .jh-pro-table ::v-deep .v-data-table > .v-data-table__wrapper > table > tbody > tr.v-data-table__selected:hover {
2393
+ background-color: #D1EDFF !important;
2394
+ }
2395
+
2396
+ /* 优化选中行的过渡效果 */
2397
+ .jh-pro-table ::v-deep .v-data-table > .v-data-table__wrapper > table > tbody > tr {
2398
+ transition: background-color 0.2s ease;
2399
+ }
2400
+
2341
2401
  /* Flex 工具类(如果没有 Tailwind) */
2342
2402
  .flex {
2343
2403
  display: flex;
@@ -359,8 +359,7 @@
359
359
  .v-data-table>.v-data-table__wrapper>table>tbody>tr>td,
360
360
  .v-data-table>.v-data-table__wrapper>table>tfoot>tr>td,
361
361
  .v-data-table>.v-data-table__wrapper>table>thead>tr>td {
362
- min-height: 40px;
363
- height: 40px;
362
+
364
363
  color: #333C44;
365
364
  font-size: .8125rem;
366
365
  }
@@ -1,267 +0,0 @@
1
- # JhAddressSelect - 省市区选择组件
2
-
3
- 省市区三级联动选择组件,支持自定义显示层级、标签文本和数据源。
4
-
5
- - ✅ **四级联动**: 支持省、市、区、镇四级联动选择
6
- - ✅ **自定义层级**: 可配置显示 1-4 级(仅省份、省市、省市区、省市区镇)
7
- - ✅ **自定义标签**: 支持自定义各级别的显示文本
8
- - ✅ **自定义数据**: 支持传入自定义省市区数据源
9
- - ✅ **样式透传**: 支持 Vuetify 的 outlined、dense、loading 等样式
10
- - ✅ **双向绑定**: 支持 v-model 双向数据绑定
11
- - ✅ **事件触发**: change 事件在值变化时触发
12
- - ✅ **清除功能**: 支持清除已选值
13
- - ✅ **返回完整信息**: 事件返回包�� code 和 name 的完整对象
14
- - ✅ **多种模式**: 支持普通联动选择 (select) 和级联选择 (cascader) 两种模式
15
-
16
- ## 基本用法
17
-
18
- ```vue
19
- <template>
20
- <jh-address-select
21
- v-model="address"
22
- :data="addressData"
23
- @change="handleAddressChange"
24
- ></jh-address-select>
25
- </template>
26
-
27
- <script>
28
- export default {
29
- data() {
30
- return {
31
- address: { province: null, city: null, district: null, town: null },
32
- addressData: [
33
- { code: '110000', name: '北京市', children: [...] },
34
- { code: '440000', name: '广东省', children: [...] }
35
- ]
36
- };
37
- },
38
- methods: {
39
- handleAddressChange(value) {
40
- console.log('省份:', value.province?.name, value.province?.code);
41
- console.log('城市:', value.city?.name, value.city?.code);
42
- console.log('区县:', value.district?.name, value.district?.code);
43
- console.log('乡镇:', value.town?.name, value.town?.code);
44
- }
45
- }
46
- };
47
- </script>
48
- ```
49
-
50
- ## API
51
-
52
- ### Props
53
-
54
- | 参数 | 说明 | 类型 | 默认值 |
55
- | --- | --- | --- | --- |
56
- | value / v-model | 绑定值,返回包含 code 和 name 的对象 | object | { province: null, city: null, district: null } |
57
- | level | 显示层级:1-仅省份,2-省市,3-省市区,4-省市区镇 | number | 3 |
58
- | type | 显示模式:'select' (默认) 或 'cascader' | string | 'select' |
59
- | label | 级联模式下的输入框标签 | string | '请选择地区' |
60
- | outlined | 是否使用 outlined 样式 | boolean | true |
61
- | dense | 是否使用紧凑模式 | boolean | false |
62
- | loading | 是否显示加载状态 | boolean | false |
63
- | labels | 自定义标签文本 | object | { province: '省份', city: '城市', district: '区/县', town: '乡镇' } |
64
- | data | 省市区数据源 | array | 内置示例数据 |
65
-
66
- ### Events
67
-
68
- | 事件名 | 说明 | 回调参数 |
69
- | --- | --- | --- |
70
- | input | 值变化时触发(v-model) | (value: object) |
71
- | change | 值变化时触发 | (value: object) |
72
-
73
- ### 返回值格式
74
-
75
- v-model 绑定值和事件回调参数的格式:
76
-
77
- ```javascript
78
- {
79
- province: { code: '440000', name: '广东省' },
80
- city: { code: '440300', name: '深圳市' },
81
- district: { code: '440305', name: '南山区' },
82
- town: { code: '440305001', name: '南头街道' } // level=4 时存在
83
- }
84
- ```
85
-
86
- 每个字段都是一个对象,包含 `code`(编码)和 `name`(名称)两个属性。未选择时为 `null`。
87
-
88
- ### 数据格式
89
-
90
- data 属性需要符合以下格式:
91
-
92
- ```javascript
93
- [
94
- {
95
- code: '110000', // 省份编码
96
- name: '北京市', // 省份名称
97
- children: [ // 城市列表
98
- {
99
- code: '110100', // 城市编码
100
- name: '市辖区', // 城市名称
101
- children: [ // 区县列表
102
- {
103
- code: '110101', // 区县编码
104
- name: '东城区' // 区县名称
105
- }
106
- ]
107
- }
108
- ]
109
- }
110
- ]
111
- ```
112
-
113
- ## 使用示例
114
-
115
- ### 默认三级联动
116
-
117
- ```vue
118
- <jh-address-select
119
- v-model="address"
120
- :data="addressData"
121
- ></jh-address-select>
122
- ```
123
-
124
- ### 级联选择模式
125
-
126
- 使用 `type="cascader"` 开启级联选择模式。
127
-
128
- ```vue
129
- <jh-address-select
130
- v-model="address"
131
- type="cascader"
132
- label="收货地址"
133
- :data="addressData"
134
- ></jh-address-select>
135
- ```
136
-
137
- ### 仅选择到城市
138
-
139
- ```vue
140
- <jh-address-select
141
- v-model="address"
142
- :level="2"
143
- :data="addressData"
144
- ></jh-address-select>
145
- ```
146
-
147
- ### 仅选择省份
148
-
149
- ```vue
150
- <jh-address-select
151
- v-model="address"
152
- :level="1"
153
- :data="addressData"
154
- ></jh-address-select>
155
- ```
156
-
157
- ### 四级联动(省市区镇)
158
-
159
- ```vue
160
- <jh-address-select
161
- v-model="address"
162
- :level="4"
163
- :data="addressData"
164
- ></jh-address-select>
165
- ```
166
-
167
- ### 四级联动(带初始值)
168
-
169
- ```vue
170
- <jh-address-select
171
- v-model="address"
172
- :level="4"
173
- :data="addressData"
174
- ></jh-address-select>
175
-
176
- <script>
177
- export default {
178
- data() {
179
- return {
180
- address: {
181
- province: { code: '440000', name: '广东省' },
182
- city: { code: '440300', name: '深圳市' },
183
- district: { code: '440305', name: '南山区' },
184
- town: { code: '440305001', name: '南头街道' }
185
- }
186
- };
187
- }
188
- };
189
- </script>
190
- ```
191
-
192
- ### 紧凑模式
193
-
194
- ```vue
195
- <jh-address-select
196
- v-model="address"
197
- dense
198
- :data="addressData"
199
- ></jh-address-select>
200
- ```
201
-
202
- ### 自定义标签文本
203
-
204
- ```vue
205
- <jh-address-select
206
- v-model="address"
207
- :labels="{ province: '所在省份', city: '所在城市', district: '所在区县' }"
208
- :data="addressData"
209
- ></jh-address-select>
210
- ```
211
-
212
- ### 加载状态
213
-
214
- ```vue
215
- <jh-address-select
216
- v-model="address"
217
- :loading="isLoading"
218
- :data="addressData"
219
- ></jh-address-select>
220
- ```
221
-
222
- ### 使用 filled 样式
223
-
224
- ```vue
225
- <jh-address-select
226
- v-model="address"
227
- :outlined="false"
228
- :data="addressData"
229
- ></jh-address-select>
230
- ```
231
-
232
- ### 监听变化
233
-
234
- ```vue
235
- <template>
236
- <jh-address-select
237
- v-model="address"
238
- :data="addressData"
239
- @change="handleAddressChange"
240
- ></jh-address-select>
241
- </template>
242
-
243
- <script>
244
- export default {
245
- methods: {
246
- handleAddressChange(value) {
247
- console.log('地址变化:', value);
248
- }
249
- }
250
- };
251
- </script>
252
- ```
253
-
254
- ## 注意事项
255
-
256
- 1. **数据格式**: data 属性必须符合指定的嵌套格式,包含 code 和 name 字段
257
- 2. **层级控制**: level 属性控制显示的级数,设置为 1 时只显示省份,2 时显示省市,3 时显示省市区,4 时显示省市区镇
258
- 3. **联动逻辑**: 选择省份后会清空城市、区县和乡镇,选择城市后会清空区县和乡镇,选择区县后会清空乡镇
259
- 4. **禁用状态**: 未选择上级时,下级选择器会自动禁用
260
- 5. **响应式布局**: 组件会根据 level 自动调整栅格布局(level=1 时占 12 列,level=2 时占 6 列,level=3 时占 4 列,level=4 时占 3 列)
261
- 6. **返回值格式**: v-model 和事件返回的值包含 code 和 name 两个字段,方便获取编码和名称
262
- 7. **级联模式**: 在 cascader 模式下,点击省份/城市/区县会展示下一级列表,直到选择完指定 level 级数后自动收起菜单
263
-
264
- ## 相关链接
265
-
266
- - [Vuetify Autocomplete](https://vuetifyjs.com/en/components/autocompletes/)
267
- - [中国行政区划代码](http://www.mca.gov.cn/article/sj/xzqh/)