uview-plus 3.4.46 → 3.4.48

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
@@ -12,7 +12,7 @@
12
12
 
13
13
  ## 说明
14
14
 
15
- uview-plus,是uni-app全面兼容vue3/nvue/鸿蒙/uni-app-x的uni-app生态框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水。uview-plus是基于uView2.x移植的支持vue3的版本,感谢uView。
15
+ uview-plus,是uni-app全面兼容vue3/nvue/鸿蒙/uni-app-x(即将发布)的uni-app生态框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水。uview-plus是基于uView2.x移植的支持vue3的版本,感谢uView。
16
16
 
17
17
  ## 可视化设计
18
18
 
package/changelog.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## 3.4.48(2025-07-10)
2
+ fix: 官方文档Card示例组件多行显示省略号样式异常
3
+
4
+ feat: album组件支持自定义preview事件
5
+
6
+ ## 3.4.47(2025-07-09)
7
+ fix: 修复datetime-picker打开时,数值可能出现对不上的问题
8
+
9
+ feat: Subsection 分段器添加支持从 list中读取激活文字颜色和未激活文字颜色
10
+
11
+ fix: 修复modal定义confirmButton
12
+
13
+ fix: safe-bottom底部安全距离在小程序优先用JS计算
14
+
15
+ feat: 新增tree树形组件
16
+
1
17
  ## 3.4.46(2025-07-08)
2
18
  feat: 上传组件预览视频支持videoPreviewObjectFit参数
3
19
 
@@ -13,7 +13,7 @@
13
13
  v-for="(item, index1) in arr"
14
14
  :key="index1"
15
15
  :style="[imageStyle(index + 1, index1 + 1)]"
16
- @tap="previewFullImage ? onPreviewTap($event, getSrc(item)) : ''"
16
+ @tap="onPreviewTap($event, getSrc(item))"
17
17
  >
18
18
  <image
19
19
  :src="getSrc(item)"
@@ -185,6 +185,7 @@ export default {
185
185
  return width
186
186
  }
187
187
  },
188
+ emits: ['preview', 'albumWidth'],
188
189
  methods: {
189
190
  addUnit,
190
191
  // 预览图片
@@ -192,12 +193,19 @@ export default {
192
193
  const urls = this.urls.map((item) => {
193
194
  return this.getSrc(item)
194
195
  })
195
- uni.previewImage({
196
- current: url,
197
- urls
198
- })
199
- // 是否阻止事件传播
200
- this.stop && this.preventEvent(e)
196
+ if (this.previewFullImage) {
197
+ uni.previewImage({
198
+ current: url,
199
+ urls
200
+ })
201
+ // 是否阻止事件传播
202
+ this.stop && this.preventEvent(e)
203
+ } else {
204
+ this.$emit('preview', {
205
+ urls,
206
+ currentIndex: urls.indexOf(url)
207
+ })
208
+ }
201
209
  },
202
210
  // 获取图片的路径
203
211
  getSrc(item) {
@@ -109,6 +109,12 @@
109
109
  watch: {
110
110
  show(newValue, oldValue) {
111
111
  if (newValue) {
112
+ // #ifdef VUE3
113
+ this.innerValue = this.correctValue(this.modelValue)
114
+ // #endif
115
+ // #ifdef VUE2
116
+ this.innerValue = this.correctValue(this.value)
117
+ // #endif
112
118
  this.updateColumnValue(this.innerValue)
113
119
  }
114
120
  },
@@ -95,7 +95,7 @@
95
95
  // console.log('内置字体图标加载成功');
96
96
  },
97
97
  fail() {
98
- console.error('内置字体图标加载出错');
98
+ // console.error('内置字体图标加载出错');
99
99
  }
100
100
  });
101
101
  if (config.customIcon.family) {
@@ -106,7 +106,7 @@
106
106
  // console.log('扩展字体图标加载成功');
107
107
  },
108
108
  fail() {
109
- console.error('扩展字体图标加载出错');
109
+ // console.error('扩展字体图标加载出错');
110
110
  }
111
111
  });
112
112
  }
@@ -34,7 +34,7 @@
34
34
  computed: {
35
35
  style() {
36
36
  const style = {};
37
- // #ifdef APP-NVUE || MP-TOUTIAO
37
+ // #ifdef APP-NVUE || MP
38
38
  // nvue下,高度使用js计算填充
39
39
  style.height = addUnit(getWindowInfo().safeAreaInsets.bottom, 'px');
40
40
  // #endif
@@ -1,5 +1,6 @@
1
- import { defineMixin } from '../../libs/vue'
1
+ import {defineMixin} from '../../libs/vue'
2
2
  import defProps from '../../libs/config/props.js'
3
+
3
4
  export const props = defineMixin({
4
5
  props: {
5
6
  // tab的数据
@@ -42,10 +43,20 @@ export const props = defineMixin({
42
43
  type: String,
43
44
  default: () => defProps.subsection.bgColor
44
45
  },
45
- // 从list元素对象中读取的键名
46
- keyName: {
47
- type: String,
48
- default: () => defProps.subsection.keyName
49
- }
46
+ // 从list元素对象中读取的键名
47
+ keyName: {
48
+ type: String,
49
+ default: () => defProps.subsection.keyName
50
+ },
51
+ // 从`list`元素对象中读取激活时的颜色 如果存在字段 优先级大于 activeColor
52
+ activeColorKeyName: {
53
+ type: String,
54
+ default: () => defProps.subsection.activeColorKeyName
55
+ },
56
+ // 从`list`元素对象中读取未激活时的颜色 如果存在字段 优先级大于 inactiveColor
57
+ inactiveColorKeyName: {
58
+ type: String,
59
+ default: () => defProps.subsection.inactiveColorKeyName
60
+ }
50
61
  }
51
62
  })
@@ -18,6 +18,8 @@ export default {
18
18
  fontSize: 12,
19
19
  bold: true,
20
20
  bgColor: '#eeeeef',
21
- keyName: 'name'
21
+ keyName: 'name',
22
+ activeColorKeyName: 'activeColorKey',
23
+ inactiveColorKeyName: 'inactiveColorKey',
22
24
  }
23
25
  }
@@ -40,7 +40,7 @@
40
40
  >
41
41
  <text
42
42
  class="u-subsection__item__text"
43
- :style="[textStyle(index)]"
43
+ :style="[textStyle(index,item)]"
44
44
  >{{ getText(item) }}</text
45
45
  >
46
46
  </view>
@@ -158,22 +158,46 @@ export default {
158
158
  };
159
159
  },
160
160
  // 分段器文字颜色
161
- textStyle(index) {
162
- return (index) => {
161
+ textStyle(index,item) {
162
+ return (index,item) => {
163
163
  const style = {};
164
164
  style.fontWeight =
165
165
  this.bold && this.innerCurrent === index ? "bold" : "normal";
166
166
  style.fontSize = addUnit(this.fontSize);
167
+
168
+ let activeColorTemp = null;
169
+ let inactiveColorTemp = null;
170
+ // 如果是对象并且设置了对应的背景色字段 则优先使用设置的字段
171
+ if(typeof item === 'object' && item[this.activeColorKeyName]){
172
+ activeColorTemp = item[this.activeColorKeyName];
173
+ }
174
+ if(typeof item === 'object' && item[this.inactiveColorKeyName]){
175
+ inactiveColorTemp = item[this.inactiveColorKeyName];
176
+ }
177
+
167
178
  // subsection模式下,激活时默认为白色的文字
168
179
  if (this.mode === "subsection") {
169
- style.color =
170
- this.innerCurrent === index ? "#fff" : this.inactiveColor;
171
- } else {
180
+ // 判断当前是否激活
181
+ if(this.innerCurrent === index){
182
+ // 判断当前是否有自定义的颜色
183
+ style.color = activeColorTemp ? activeColorTemp : '#FFF'
184
+ // style.color = activeColorTemp ? activeColorTemp : this.activeColor
185
+ }
186
+ else{
187
+ // 判断当前是否有自定义的颜色
188
+ style.color = inactiveColorTemp ? inactiveColorTemp : this.inactiveColor;
189
+ }
190
+ }
191
+ else {
172
192
  // button模式下,激活时文字颜色默认为activeColor
173
- style.color =
174
- this.innerCurrent === index
175
- ? this.activeColor
176
- : this.inactiveColor;
193
+ if(this.innerCurrent === index){
194
+ // 判断当前是否有自定义的颜色
195
+ style.color = activeColorTemp ? activeColorTemp : this.activeColor
196
+ }
197
+ else{
198
+ // 判断当前是否有自定义的颜色
199
+ style.color = inactiveColorTemp ? inactiveColorTemp : this.inactiveColor;
200
+ }
177
201
  }
178
202
  return style;
179
203
  };
@@ -0,0 +1,128 @@
1
+ <template>
2
+ <view class="u-tree-node" :style="{ paddingLeft: depth * 20 + 'px' }">
3
+ <view class="u-tree-node-content" @click="toggle">
4
+ <!-- <text v-if="hasChildren" class="u-tree-node-toggle">
5
+ {{ node.expanded ? '▼' : '▶' }}
6
+ </text> -->
7
+ <up-icon v-if="hasChildren" class="u-tree-node-toggle"
8
+ :name="node.expanded ? 'arrow-down-fill' : 'play-right-fill'" size="12" />
9
+ <up-checkbox
10
+ v-if="showCheckbox"
11
+ usedAlone
12
+ :size="12"
13
+ :checked="node.checked"
14
+ @change="toggleCheck"
15
+ style="margin-right: 10px;"
16
+ />
17
+ <slot :nodeData="node" :level="depth + 1">
18
+ {{ node[props.label] }}
19
+ </slot>
20
+ </view>
21
+ <view v-if="hasChildren && (node.expanded === undefined ? true : node.expanded)"
22
+ class="u-tree-node-children"
23
+ :style="{ paddingLeft: (depth + 1) * 20 + 'px' }">
24
+ <tree-node
25
+ v-for="child in node[props.children]"
26
+ :key="child[props.nodeKey]"
27
+ :node="child"
28
+ :props="props"
29
+ :show-checkbox="showCheckbox"
30
+ :check-strictly="checkStrictly"
31
+ :expand-on-click-node="expandOnClickNode"
32
+ :depth="depth + 1"
33
+ @node-click="$emit('node-click', $event)"
34
+ @check-change="$emit('check-change', $event)">
35
+ <template #default="{ nodeData, level }">
36
+ <slot name="default" :nodeData="nodeData" :level="level"></slot>
37
+ </template>
38
+ </tree-node>
39
+ </view>
40
+ </view>
41
+ </template>
42
+
43
+ <script>
44
+ export default {
45
+ name: 'tree-node',
46
+ props: {
47
+ node: {
48
+ type: Object,
49
+ required: true
50
+ },
51
+ props: {
52
+ type: Object,
53
+ required: true
54
+ },
55
+ showCheckbox: {
56
+ type: Boolean,
57
+ default: false
58
+ },
59
+ checkStrictly: {
60
+ type: Boolean,
61
+ default: false
62
+ },
63
+ expandOnClickNode: {
64
+ type: Boolean,
65
+ default: true
66
+ },
67
+ depth: {
68
+ type: Number,
69
+ default: 0
70
+ }
71
+ },
72
+ computed: {
73
+ hasChildren() {
74
+ return this.node[this.props.children] && this.node[this.props.children].length > 0;
75
+ },
76
+ isExpanded() {
77
+ return this.node.expanded === undefined ? false : this.node.expanded;
78
+ }
79
+ },
80
+ emits: ['node-click', 'check-change'],
81
+ methods: {
82
+ toggle() {
83
+ if (this.expandOnClickNode && this.hasChildren) {
84
+ this.node.expanded = !this.node.expanded;
85
+ }
86
+ this.$emit('node-click', this.node);
87
+ },
88
+ toggleCheck(checked) {
89
+ this.node.checked = checked;
90
+ if (!this.checkStrictly) {
91
+ this.updateChildCheckStatus(this.node, checked);
92
+ this.updateParentCheckStatus(this.node);
93
+ }
94
+ this.$emit('check-change', this.node);
95
+ },
96
+ updateChildCheckStatus(node, checked) {
97
+ if (node[this.props.children]) {
98
+ node[this.props.children].forEach(child => {
99
+ child.checked = checked;
100
+ this.updateChildCheckStatus(child, checked);
101
+ });
102
+ }
103
+ },
104
+ updateParentCheckStatus(node) {
105
+ let parent = this.$parent;
106
+ while (parent && parent.node) {
107
+ const allChecked = parent.node[this.props.children].every(
108
+ child => child.checked
109
+ );
110
+ parent.node.checked = allChecked;
111
+ parent = parent.$parent;
112
+ }
113
+ }
114
+ }
115
+ };
116
+ </script>
117
+
118
+ <style scoped>
119
+ .u-tree-node-content {
120
+ display: flex;
121
+ flex-direction: row;
122
+ align-items: center;
123
+ padding-left: 20px;
124
+ }
125
+ .u-tree-node-toggle {
126
+ margin-right: 5px;
127
+ }
128
+ </style>
@@ -0,0 +1,117 @@
1
+ <template>
2
+ <view class="u-tree">
3
+ <tree-node
4
+ v-for="node in treeData"
5
+ :key="node[props.nodeKey]"
6
+ :node="node"
7
+ :props="props"
8
+ :show-checkbox="showCheckbox"
9
+ :check-strictly="checkStrictly"
10
+ :expand-on-click-node="expandOnClickNode"
11
+ @node-click="handleNodeClick"
12
+ @check-change="$emit('check-change', $event)">
13
+ <template #default="{ nodeData, level }">
14
+ <slot :node="nodeData" :level="level"></slot>
15
+ </template>
16
+ </tree-node>
17
+ </view>
18
+ </template>
19
+
20
+ <script>
21
+ import TreeNode from './tree-node.vue';
22
+
23
+ export default {
24
+ name: 'u-tree',
25
+ components: { TreeNode },
26
+ props: {
27
+ data: {
28
+ type: Array,
29
+ required: true
30
+ },
31
+ props: {
32
+ type: Object,
33
+ default: () => ({
34
+ label: 'label',
35
+ children: 'children',
36
+ nodeKey: 'id'
37
+ })
38
+ },
39
+ showCheckbox: {
40
+ type: Boolean,
41
+ default: false
42
+ },
43
+ defaultExpandAll: {
44
+ type: Boolean,
45
+ default: false
46
+ },
47
+ expandOnClickNode: {
48
+ type: Boolean,
49
+ default: true
50
+ },
51
+ checkStrictly: {
52
+ type: Boolean,
53
+ default: false
54
+ }
55
+ },
56
+ data() {
57
+ return {
58
+ treeData: []
59
+ };
60
+ },
61
+ created() {
62
+ this.initTree();
63
+ },
64
+ watch: {
65
+ data: {
66
+ handler(newVal) {
67
+ this.treeData = JSON.parse(JSON.stringify(newVal));
68
+ this.initExpandedState(this.treeData, this.defaultExpandAll);
69
+ },
70
+ deep: true,
71
+ immediate: true
72
+ }
73
+ },
74
+ emits: ['node-click', 'check-change'],
75
+ methods: {
76
+ initTree() {
77
+ this.treeData = JSON.parse(JSON.stringify(this.data));
78
+ this.initExpandedState(this.treeData, this.defaultExpandAll);
79
+ },
80
+ initExpandedState(nodes, expanded) {
81
+ nodes.forEach(node => {
82
+ node.expanded = expanded;
83
+ if (node[this.props.children]) {
84
+ this.initExpandedState(node[this.props.children], expanded);
85
+ }
86
+ });
87
+ },
88
+ handleNodeClick(node) {
89
+ this.$emit('node-click', node);
90
+ },
91
+ /**
92
+ * 直接递归 treeData 获取所有 checked 的节点
93
+ */
94
+ getCheckedNodes() {
95
+ const traverse = (nodes) => {
96
+ let result = [];
97
+ nodes.forEach(node => {
98
+ if (node.checked) {
99
+ result.push(node);
100
+ }
101
+ if (node[this.props.children] && node[this.props.children].length > 0) {
102
+ result = result.concat(traverse(node[this.props.children]));
103
+ }
104
+ });
105
+ return result;
106
+ };
107
+ return traverse(this.treeData);
108
+ }
109
+ }
110
+ };
111
+ </script>
112
+
113
+ <style scoped>
114
+ .u-tree {
115
+ font-size: 28rpx;
116
+ }
117
+ </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.46",
5
+ "version": "3.4.48",
6
6
  "description": "零云®uview-plus已兼容vue3,全面的组件和便捷的工具会让您信手拈来,如鱼得水。",
7
7
  "keywords": [
8
8
  "uview",
@@ -100,7 +100,7 @@ declare interface ModalSlots {
100
100
  /**
101
101
  * 传入自定义按钮,用于在微信小程序弹窗通过按钮授权的场景
102
102
  */
103
- ['confirm-button']?: () => any
103
+ ['confirmButton']?: () => any
104
104
  }
105
105
 
106
106
  declare interface _Modal {
@@ -46,6 +46,17 @@ declare interface SubsectionProps {
46
46
  * @default "name"
47
47
  */
48
48
  keyName?: string
49
+
50
+ /**
51
+ * 从`list`元素对象中读取激活时的颜色 如果存在字段 优先级大于 activeColor
52
+ * @default activeColorKey
53
+ */
54
+ activeColorKeyName?: string
55
+ /**
56
+ * 从`list`元素对象中读取未激活时的颜色 如果存在字段 优先级大于 inactiveColor
57
+ * @default inactiveColorKey
58
+ */
59
+ inactiveColorKeyName?: string
49
60
  /**
50
61
  * 分段器选项发生改变时触发
51
62
  * @param index 选项的index索引值,从0开始