uview-plus 3.4.79 → 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,9 @@
1
+ ## 3.4.81(2025-08-10)
2
+ feat: table2新增树状结构递归支持
3
+
4
+ ## 3.4.80(2025-08-10)
5
+ feat: 新增table2固定列对树状支持
6
+
1
7
  ## 3.4.79(2025-08-09)
2
8
  feat: table2组件支持左侧固定列功能
3
9
 
@@ -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,20 +143,48 @@
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>
162
+ <!-- 子级渲染 (递归组件) -->
163
+ <template v-if="isExpanded(row) && row[treeProps.children] && row[treeProps.children].length">
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
+ />
187
+ </template>
149
188
  </template>
150
189
  </template>
151
190
  </view>
@@ -155,9 +194,13 @@
155
194
 
156
195
  <script>
157
196
  import { addUnit, sleep } from '../../libs/function/index';
197
+ import tableRow from './tableRow.vue'; // 引入递归组件
158
198
 
159
199
  export default {
160
200
  name: 'u-table2',
201
+ components: {
202
+ tableRow // 注册递归组件
203
+ },
161
204
  props: {
162
205
  data: {
163
206
  type: Array,
@@ -292,6 +335,15 @@ export default {
292
335
  type: String,
293
336
  default: '暂无数据'
294
337
  },
338
+ // 添加mainCol属性,用于指定树形结构展开控制图标所在的列
339
+ mainCol: {
340
+ type: String,
341
+ default: ''
342
+ },
343
+ expandWidth: {
344
+ type: String,
345
+ default: '25px'
346
+ }
295
347
  },
296
348
  emits: [
297
349
  'select', 'select-all', 'selection-change',
@@ -311,7 +363,9 @@ export default {
311
363
  showFixedColumnShadow: false, // 是否显示固定列阴影
312
364
  fixedLeftColumns: [], // 左侧固定列
313
365
  tableHeight: 'auto', // 表格高度
314
- rowHeight: 40 // 行高
366
+ rowHeight: 40, // 行高
367
+ headerHeight: 'auto', // 新增表头高度属性
368
+ hasTree: false // 新增属性,用于判断是否存在树形结构
315
369
  }
316
370
  },
317
371
  mounted() {
@@ -384,6 +438,17 @@ export default {
384
438
  }
385
439
 
386
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;
387
452
  }
388
453
  },
389
454
  watch: {
@@ -456,9 +521,12 @@ export default {
456
521
  cellStyleInner(scope) {
457
522
  let style = {
458
523
  width: scope.column?.width ? addUnit(scope.column.width) : 'auto',
459
- flex: scope.column?.width ? 'none' : 1,
460
- paddingLeft: (24 * scope.level) + 'px'
524
+ flex: scope.column?.width ? 'none' : 1
461
525
  };
526
+ // 只有展开列设置padding
527
+ if (scope.column.key == this.computedMainCol) {
528
+ style.paddingLeft = (16 * (scope.level || 0)) + 2 + 'px'
529
+ }
462
530
  if (this.cellStyle != null) {
463
531
  let styleCalc = this.cellStyle(scope)
464
532
  if (styleCalc != null) {
@@ -475,10 +543,17 @@ export default {
475
543
  this.scrollWidth = size.width + 'px'
476
544
  })
477
545
 
478
- // 获取表格高度
479
- this.$uGetRect('.u-table2').then(size => {
480
- this.tableHeight = size.height + 'px';
546
+ // 获取表头高度并设置
547
+ this.$uGetRect('.u-table-header').then(size => {
548
+ if (size.height) {
549
+ this.headerHeight = size.height + 'px';
550
+ }
481
551
  })
552
+
553
+ // 遍历数据列表第一层判断是否存在树形结构
554
+ this.hasTree = this.data.some(item => {
555
+ return item[this.treeProps.children] && item[this.treeProps.children].length > 0;
556
+ });
482
557
  },
483
558
  // 将setup中的函数转换为methods
484
559
  handleRowClick(row) {
@@ -541,6 +616,7 @@ export default {
541
616
  return this.selectedRows.some(r => r[this.rowKey] === row[this.rowKey]);
542
617
  },
543
618
  toggleExpand(row) {
619
+ console.log(row)
544
620
  const key = row[this.rowKey];
545
621
  const index = this.expandedKeys.indexOf(key);
546
622
  if (index === -1) {
@@ -558,10 +634,6 @@ export default {
558
634
  </script>
559
635
 
560
636
  <style lang="scss" scoped>
561
- .u-table2-wrapper {
562
- position: relative;
563
- }
564
-
565
637
  .u-table2 {
566
638
  width: auto;
567
639
  overflow: auto;
@@ -590,21 +662,36 @@ export default {
590
662
  display: flex;
591
663
  flex-direction: row;
592
664
  align-items: center;
593
- border-bottom: 1rpx solid #ebeef5;
665
+ border-bottom: 1px solid #ebeef5;
594
666
  overflow: hidden;
595
667
  position: relative;
596
- 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
+ }
597
683
  }
598
684
 
599
685
  .u-table-cell {
600
686
  flex: 1;
601
687
  display: flex;
602
688
  flex-direction: row;
603
- padding: 5px 4px;
689
+ padding: 10px 10px;
604
690
  font-size: 14px;
605
691
  white-space: nowrap;
606
692
  overflow: hidden;
607
693
  text-overflow: ellipsis;
694
+ line-height: 1.1;
608
695
  }
609
696
 
610
697
  .u-table-row-zebra {
@@ -646,23 +733,22 @@ export default {
646
733
  background-color: #ffffff;
647
734
  }
648
735
 
649
- .u-table-fixed-row {
650
- display: flex;
651
- flex-direction: row;
652
- align-items: center;
653
- border-bottom: 1rpx solid #ebeef5;
654
- position: relative;
655
- }
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
+ // }
656
743
 
657
- .u-table-fixed-cell {
658
- flex: 1;
659
- display: flex;
660
- flex-direction: row;
661
- padding: 5px 4px;
662
- font-size: 14px;
663
- white-space: nowrap;
664
- overflow: hidden;
665
- text-overflow: ellipsis;
666
- 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
+ }
667
753
  }
668
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.79",
5
+ "version": "3.4.81",
6
6
  "description": "零云®uview-plus已兼容vue3,100+全面的组件和便捷的工具会让您信手拈来,如鱼得水。",
7
7
  "keywords": [
8
8
  "uview",