uview-plus 3.4.80 → 3.4.81

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/changelog.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 3.4.81(2025-08-10)
2
+ feat: table2新增树状结构递归支持
3
+
1
4
  ## 3.4.80(2025-08-10)
2
5
  feat: 新增table2固定列对树状支持
3
6
 
@@ -0,0 +1,207 @@
1
+ <style lang="scss" scoped>
2
+ .u-table-row {
3
+ display: flex;
4
+ flex-direction: row;
5
+ align-items: center;
6
+ border-bottom: 1px solid #ebeef5;
7
+ overflow: hidden;
8
+ position: relative;
9
+ }
10
+
11
+ // 添加border样式支持
12
+ .u-table-border {
13
+ border-top: 1px solid #ebeef5;
14
+ border-left: 1px solid #ebeef5;
15
+ border-right: 1px solid #ebeef5;
16
+ .u-table-cell {
17
+ border-right: 1px solid #ebeef5;
18
+ }
19
+
20
+ .u-table-cell:last-child {
21
+ border-right: none;
22
+ }
23
+ }
24
+
25
+ .u-table-cell {
26
+ flex: 1;
27
+ display: flex;
28
+ flex-direction: row;
29
+ padding: 10px 10px;
30
+ font-size: 14px;
31
+ white-space: nowrap;
32
+ overflow: hidden;
33
+ text-overflow: ellipsis;
34
+ line-height: 1.1;
35
+ }
36
+
37
+ .u-table-row-zebra {
38
+ background-color: #fafafa;
39
+ }
40
+
41
+ .u-table-row-highlight {
42
+ background-color: #f5f7fa;
43
+ }
44
+
45
+ .u-table-empty {
46
+ text-align: center;
47
+ padding: 20px;
48
+ color: #999;
49
+ }
50
+
51
+ .u-text-left {
52
+ text-align: left;
53
+ }
54
+
55
+ .u-text-center {
56
+ text-align: center;
57
+ }
58
+
59
+ .u-text-right {
60
+ text-align: right;
61
+ }
62
+ </style>
63
+ <template>
64
+ <view v-for="(row, index) in rows" :key="row[rowKey]" class="u-table-row u-table-row-child u-flex-y"
65
+ style="border-bottom: 0px;">
66
+ <view class="u-table-row u-table-child-first" >
67
+ <view v-for="(col, colIndex) in columns" :key="col.key"
68
+ class="u-table-cell"
69
+ :class="[col.align ? 'u-text-' + col.align : '',
70
+ cellClassName ? cellClassName(row, col) : '',
71
+ getFixedClass(col)
72
+ ]"
73
+ :style="cellStyleInner({row: row, column: col, rowIndex: index, columnIndex: colIndex, level: level})">
74
+ <!-- 在mainCol列显示展开图标 -->
75
+ <view v-if="col.key === computedMainCol && hasTree"
76
+ @click.stop="toggleExpand(row)" :style="{width: expandWidth}">
77
+ <view v-if="row.children && row.children.length > 0">
78
+ {{ isExpanded(row) ? '▼' : '▶' }}
79
+ </view>
80
+ </view>
81
+ <slot name="cell" :row="row" :column="col" :prow="parentRow" :rowIndex="index" :columnIndex="colIndex" :level="level">
82
+ <view class="u-table-cell_content">
83
+ {{ row[col.key] }}
84
+ </view>
85
+ </slot>
86
+ </view>
87
+ </view>
88
+
89
+ <!-- 递归渲染更深层的子级 -->
90
+ <template v-if="isExpanded(row) && row[treeProps.children] && row[treeProps.children].length">
91
+ <table-row
92
+ :rows="row[treeProps.children]"
93
+ :parent-row="row"
94
+ :columns="columns"
95
+ :tree-props="treeProps"
96
+ :row-key="rowKey"
97
+ :expanded-keys="expandedKeys"
98
+ :cell-style-inner="cellStyleInner"
99
+ :is-expanded="isExpanded"
100
+ :row-class-name="rowClassName"
101
+ :stripe="stripe"
102
+ :cell-class-name="cellClassName"
103
+ :get-fixed-class="getFixedClass"
104
+ :highlight-current-row="highlightCurrentRow"
105
+ :current-row="currentRow"
106
+ :handle-row-click="handleRowClick"
107
+ :toggle-expand="toggleExpand"
108
+ :level="level + 1"
109
+ :hasTree="hasTree"
110
+ :expandWidth="expandWidth"
111
+ :computed-main-col="computedMainCol"
112
+ @row-click="$emit('rowClick', $event)"
113
+ @toggle-expand="$emit('toggleExpand', $event)"
114
+ />
115
+ </template>
116
+ </view>
117
+ </template>
118
+
119
+ <script>
120
+ export default {
121
+ name: 'tableRow',
122
+ props: {
123
+ rows: {
124
+ type: Array,
125
+ required: true
126
+ },
127
+ parentRow: {
128
+ type: Object,
129
+ required: true
130
+ },
131
+ columns: {
132
+ type: Array,
133
+ required: true
134
+ },
135
+ treeProps: {
136
+ type: Object,
137
+ required: true
138
+ },
139
+ rowKey: {
140
+ type: String,
141
+ required: true
142
+ },
143
+ expandedKeys: {
144
+ type: Array,
145
+ required: true
146
+ },
147
+ cellStyleInner: {
148
+ type: Function,
149
+ required: true
150
+ },
151
+ isExpanded: {
152
+ type: Function,
153
+ required: true
154
+ },
155
+ rowClassName: {
156
+ type: Function,
157
+ default: null
158
+ },
159
+ stripe: {
160
+ type: Boolean,
161
+ default: false
162
+ },
163
+ cellClassName: {
164
+ type: Function,
165
+ default: null
166
+ },
167
+ getFixedClass: {
168
+ type: Function,
169
+ required: true
170
+ },
171
+ highlightCurrentRow: {
172
+ type: Boolean,
173
+ default: false
174
+ },
175
+ currentRow: {
176
+ type: Object,
177
+ default: null
178
+ },
179
+ handleRowClick: {
180
+ type: Function,
181
+ required: true
182
+ },
183
+ toggleExpand: {
184
+ type: Function,
185
+ required: true
186
+ },
187
+ level: {
188
+ type: Number,
189
+ required: true
190
+ },
191
+ // 添加computedMainCol属性
192
+ computedMainCol: {
193
+ type: String,
194
+ required: true
195
+ },
196
+ expandWidth: {
197
+ type: String,
198
+ required: true
199
+ },
200
+ hasTree: {
201
+ type: Boolean,
202
+ required: false
203
+ },
204
+ },
205
+ emits: ['rowClick', 'toggleExpand']
206
+ }
207
+ </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <view class="u-table2">
2
+ <view class="u-table2" :class="{ 'u-table-border': border }">
3
3
  <scroll-view scroll-x class="u-table2-content" :style="{ height: height ? height + 'px' : 'auto' }" @scroll="onScroll">
4
4
  <!-- 表头 -->
5
5
  <view v-if="showHeader" class="u-table-header" :class="{ 'u-table-sticky': fixedHeader }" :style="{minWidth: scrollWidth}">
@@ -44,13 +44,13 @@
44
44
  <checkbox :checked="isSelected(row)"
45
45
  @click.stop="toggleSelect(row)" />
46
46
  </view>
47
-
48
47
  <!-- 树形结构展开图标 -->
49
- <view v-else-if="col.type === 'expand'" @click.stop="toggleExpand(row)">
50
- {{ isExpanded(row) ? '▼' : '▶' }}
48
+ <view v-if="col.key === computedMainCol && hasTree"
49
+ @click.stop="toggleExpand(row)" :style="{width: expandWidth}">
50
+ <view v-if="row.children && row.children.length > 0">
51
+ {{ isExpanded(row) ? '▼' : '▶' }}
52
+ </view>
51
53
  </view>
52
-
53
- <!-- 默认插槽或文本 -->
54
54
  <slot name="cell" :row="row" :column="col"
55
55
  :rowIndex="index" :columnIndex="colIndex">
56
56
  <view class="u-table-cell_content">
@@ -60,21 +60,32 @@
60
60
  </view>
61
61
  </view>
62
62
 
63
- <!-- 子级渲染 -->
63
+ <!-- 子级渲染 (递归组件) -->
64
64
  <template v-if="isExpanded(row) && row[treeProps.children] && row[treeProps.children].length">
65
- <view v-for="childRow in row[treeProps.children]" :key="childRow[rowKey]"
66
- class="u-table-row u-table-row-child">
67
- <view v-for="(col2, col2Index) in columns" :key="col2.key" class="u-table-cell"
68
- :style="cellStyleInner({row: childRow, column: col2,
69
- rowIndex: index, columnIndex: col2Index, level: 1})">
70
- <slot name="cell" :row="childRow" :column="col2" :prow="row"
71
- :rowIndex="index" :columnIndex="col2Index" :level="1">
72
- <view class="u-table-cell_content">
73
- {{ childRow[col2.key] }}
74
- </view>
75
- </slot>
76
- </view>
77
- </view>
65
+ <table-row
66
+ :rows="row[treeProps.children]"
67
+ :parent-row="row"
68
+ :columns="columns"
69
+ :tree-props="treeProps"
70
+ :row-key="rowKey"
71
+ :expanded-keys="expandedKeys"
72
+ :cell-style-inner="cellStyleInner"
73
+ :is-expanded="isExpanded"
74
+ :row-class-name="rowClassName"
75
+ :stripe="stripe"
76
+ :cell-class-name="cellClassName"
77
+ :get-fixed-class="getFixedClass"
78
+ :highlight-current-row="highlightCurrentRow"
79
+ :current-row="currentRow"
80
+ :handle-row-click="handleRowClick"
81
+ :toggle-expand="toggleExpand"
82
+ :level="1"
83
+ :hasTree="hasTree"
84
+ :expandWidth="expandWidth"
85
+ :computedMainCol="computedMainCol"
86
+ @row-click="handleRowClick"
87
+ @toggle-expand="toggleExpand"
88
+ />
78
89
  </template>
79
90
  </template>
80
91
  </template>
@@ -90,7 +101,7 @@
90
101
  <view v-if="showFixedColumnShadow" class="u-table-fixed-shadow" :style="{ height: tableHeight }">
91
102
  <!-- 表头 -->
92
103
  <view v-if="showHeader" class="u-table-header" :class="{ 'u-table-sticky': fixedHeader }" :style="{minWidth: scrollWidth}">
93
- <view class="u-table-row">
104
+ <view class="u-table-row" :style="{height: headerHeight}">
94
105
  <view v-for="(col, colIndex) in visibleFixedLeftColumns" :key="col.key" class="u-table-cell"
95
106
  :style="headerColStyle(col)"
96
107
  :class="[col.align ? 'u-text-' + col.align : '',
@@ -132,35 +143,47 @@
132
143
  @click.stop="toggleSelect(row)" />
133
144
  </view>
134
145
 
135
- <!-- 树形结构展开图标 -->
136
- <view v-else-if="col.type === 'expand'" @click.stop="toggleExpand(row)">
137
- {{ isExpanded(row) ? '▼' : '▶' }}
138
- </view>
139
-
140
146
  <!-- 默认插槽或文本 -->
141
147
  <slot name="cell" :row="row" :column="col"
142
148
  :rowIndex="index" :columnIndex="colIndex">
149
+ <!-- 树形结构展开图标 -->
150
+ <view v-if="col.key === computedMainCol"
151
+ @click.stop="toggleExpand(row)" :style="{width: expandWidth}">
152
+ <view v-if="row.children && row.children.length > 0">
153
+ {{ isExpanded(row) ? '▼' : '▶' }}
154
+ </view>
155
+ </view>
143
156
  <view class="u-table-cell_content">
144
157
  {{ row[col.key] }}
145
158
  </view>
146
159
  </slot>
147
160
  </view>
148
161
  </view>
149
- <!-- 子级渲染 -->
162
+ <!-- 子级渲染 (递归组件) -->
150
163
  <template v-if="isExpanded(row) && row[treeProps.children] && row[treeProps.children].length">
151
- <view v-for="childRow in row[treeProps.children]" :key="childRow[rowKey]"
152
- class="u-table-row u-table-row-child">
153
- <view v-for="(col2, col2Index) in visibleFixedLeftColumns" :key="col2.key" class="u-table-cell"
154
- :style="cellStyleInner({row: childRow, column: col2,
155
- rowIndex: index, columnIndex: col2Index, level: 1})">
156
- <slot name="cell" :row="childRow" :column="col2" :prow="row"
157
- :rowIndex="index" :columnIndex="col2Index" :level="1">
158
- <view class="u-table-cell_content">
159
- {{ childRow[col2.key] }}
160
- </view>
161
- </slot>
162
- </view>
163
- </view>
164
+ <table-row
165
+ :rows="row[treeProps.children]"
166
+ :parent-row="row"
167
+ :columns="visibleFixedLeftColumns"
168
+ :tree-props="treeProps"
169
+ :row-key="rowKey"
170
+ :expanded-keys="expandedKeys"
171
+ :cell-style-inner="cellStyleInner"
172
+ :is-expanded="isExpanded"
173
+ :row-class-name="rowClassName"
174
+ :stripe="stripe"
175
+ :cell-class-name="cellClassName"
176
+ :get-fixed-class="getFixedClass"
177
+ :highlight-current-row="highlightCurrentRow"
178
+ :current-row="currentRow"
179
+ :handle-row-click="handleRowClick"
180
+ :toggle-expand="toggleExpand"
181
+ :level="1"
182
+ :expandWidth="expandWidth"
183
+ :computedMainCol="computedMainCol"
184
+ @row-click="handleRowClick"
185
+ @toggle-expand="toggleExpand"
186
+ />
164
187
  </template>
165
188
  </template>
166
189
  </template>
@@ -171,9 +194,13 @@
171
194
 
172
195
  <script>
173
196
  import { addUnit, sleep } from '../../libs/function/index';
197
+ import tableRow from './tableRow.vue'; // 引入递归组件
174
198
 
175
199
  export default {
176
200
  name: 'u-table2',
201
+ components: {
202
+ tableRow // 注册递归组件
203
+ },
177
204
  props: {
178
205
  data: {
179
206
  type: Array,
@@ -308,6 +335,15 @@ export default {
308
335
  type: String,
309
336
  default: '暂无数据'
310
337
  },
338
+ // 添加mainCol属性,用于指定树形结构展开控制图标所在的列
339
+ mainCol: {
340
+ type: String,
341
+ default: ''
342
+ },
343
+ expandWidth: {
344
+ type: String,
345
+ default: '25px'
346
+ }
311
347
  },
312
348
  emits: [
313
349
  'select', 'select-all', 'selection-change',
@@ -327,7 +363,9 @@ export default {
327
363
  showFixedColumnShadow: false, // 是否显示固定列阴影
328
364
  fixedLeftColumns: [], // 左侧固定列
329
365
  tableHeight: 'auto', // 表格高度
330
- rowHeight: 40 // 行高
366
+ rowHeight: 40, // 行高
367
+ headerHeight: 'auto', // 新增表头高度属性
368
+ hasTree: false // 新增属性,用于判断是否存在树形结构
331
369
  }
332
370
  },
333
371
  mounted() {
@@ -400,6 +438,17 @@ export default {
400
438
  }
401
439
 
402
440
  return visibleColumns;
441
+ },
442
+ // 获取mainCol的值,如果未设置则默认为第一列的key
443
+ computedMainCol() {
444
+ if (this.mainCol) {
445
+ return this.mainCol;
446
+ }
447
+ // 修改为排除有type值的列
448
+ const validColumns = this.columns.filter(col => !col.type);
449
+ let mainCol = validColumns && validColumns.length > 0 ? validColumns[0].key : '';
450
+ console.log('mainCol', mainCol)
451
+ return mainCol;
403
452
  }
404
453
  },
405
454
  watch: {
@@ -472,9 +521,12 @@ export default {
472
521
  cellStyleInner(scope) {
473
522
  let style = {
474
523
  width: scope.column?.width ? addUnit(scope.column.width) : 'auto',
475
- flex: scope.column?.width ? 'none' : 1,
476
- paddingLeft: (24 * scope.level) + 'px'
524
+ flex: scope.column?.width ? 'none' : 1
477
525
  };
526
+ // 只有展开列设置padding
527
+ if (scope.column.key == this.computedMainCol) {
528
+ style.paddingLeft = (16 * (scope.level || 0)) + 2 + 'px'
529
+ }
478
530
  if (this.cellStyle != null) {
479
531
  let styleCalc = this.cellStyle(scope)
480
532
  if (styleCalc != null) {
@@ -491,10 +543,17 @@ export default {
491
543
  this.scrollWidth = size.width + 'px'
492
544
  })
493
545
 
494
- // 获取表格高度
495
- // this.$uGetRect('.u-table2').then(size => {
496
- // this.tableHeight = size.height + 'px';
497
- // })
546
+ // 获取表头高度并设置
547
+ this.$uGetRect('.u-table-header').then(size => {
548
+ if (size.height) {
549
+ this.headerHeight = size.height + 'px';
550
+ }
551
+ })
552
+
553
+ // 遍历数据列表第一层判断是否存在树形结构
554
+ this.hasTree = this.data.some(item => {
555
+ return item[this.treeProps.children] && item[this.treeProps.children].length > 0;
556
+ });
498
557
  },
499
558
  // 将setup中的函数转换为methods
500
559
  handleRowClick(row) {
@@ -557,6 +616,7 @@ export default {
557
616
  return this.selectedRows.some(r => r[this.rowKey] === row[this.rowKey]);
558
617
  },
559
618
  toggleExpand(row) {
619
+ console.log(row)
560
620
  const key = row[this.rowKey];
561
621
  const index = this.expandedKeys.indexOf(key);
562
622
  if (index === -1) {
@@ -574,10 +634,6 @@ export default {
574
634
  </script>
575
635
 
576
636
  <style lang="scss" scoped>
577
- .u-table2-wrapper {
578
- position: relative;
579
- }
580
-
581
637
  .u-table2 {
582
638
  width: auto;
583
639
  overflow: auto;
@@ -606,21 +662,36 @@ export default {
606
662
  display: flex;
607
663
  flex-direction: row;
608
664
  align-items: center;
609
- border-bottom: 1rpx solid #ebeef5;
665
+ border-bottom: 1px solid #ebeef5;
610
666
  overflow: hidden;
611
667
  position: relative;
612
- min-height: 40px;
668
+ // min-height: 40px;
669
+ }
670
+
671
+ // 添加border样式支持
672
+ &.u-table-border {
673
+ border-top: 1px solid #ebeef5;
674
+ border-left: 1px solid #ebeef5;
675
+ border-right: 1px solid #ebeef5;
676
+ .u-table-cell {
677
+ border-right: 1px solid #ebeef5;
678
+ }
679
+
680
+ .u-table-cell:last-child {
681
+ border-right: none;
682
+ }
613
683
  }
614
684
 
615
685
  .u-table-cell {
616
686
  flex: 1;
617
687
  display: flex;
618
688
  flex-direction: row;
619
- padding: 5px 4px;
689
+ padding: 10px 10px;
620
690
  font-size: 14px;
621
691
  white-space: nowrap;
622
692
  overflow: hidden;
623
693
  text-overflow: ellipsis;
694
+ line-height: 1.1;
624
695
  }
625
696
 
626
697
  .u-table-row-zebra {
@@ -662,23 +733,22 @@ export default {
662
733
  background-color: #ffffff;
663
734
  }
664
735
 
665
- .u-table-fixed-row {
666
- display: flex;
667
- flex-direction: row;
668
- align-items: center;
669
- border-bottom: 1rpx solid #ebeef5;
670
- position: relative;
671
- }
736
+ // .u-table-fixed-row {
737
+ // display: flex;
738
+ // flex-direction: row;
739
+ // align-items: center;
740
+ // border-bottom: 1rpx solid #ebeef5;
741
+ // position: relative;
742
+ // }
672
743
 
673
- .u-table-fixed-cell {
674
- flex: 1;
675
- display: flex;
676
- flex-direction: row;
677
- padding: 5px 4px;
678
- font-size: 14px;
679
- white-space: nowrap;
680
- overflow: hidden;
681
- text-overflow: ellipsis;
682
- background-color: #fff;
744
+ // 为固定列也添加border样式支持
745
+ .u-table-fixed-shadow .u-table-border {
746
+ .u-table-cell {
747
+ border-right: 1rpx solid #ebeef5;
748
+ }
749
+
750
+ .u-table-cell:last-child {
751
+ border-right: none;
752
+ }
683
753
  }
684
754
  </style>
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "id": "uview-plus",
3
3
  "name": "uview-plus",
4
4
  "displayName": "零云®uview-plus3.0重磅发布,全面的Vue3鸿蒙跨端移动组件库,组件丰富维护更新稳定。",
5
- "version": "3.4.80",
5
+ "version": "3.4.81",
6
6
  "description": "零云®uview-plus已兼容vue3,100+全面的组件和便捷的工具会让您信手拈来,如鱼得水。",
7
7
  "keywords": [
8
8
  "uview",