uview-plus 3.4.45 → 3.4.47
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 +1 -1
- package/changelog.md +20 -0
- package/components/u-datetime-picker/u-datetime-picker.vue +6 -0
- package/components/u-row-notice/u-row-notice.vue +1 -1
- package/components/u-safe-bottom/u-safe-bottom.vue +1 -1
- package/components/u-subsection/props.js +17 -6
- package/components/u-subsection/subsection.js +3 -1
- package/components/u-subsection/u-subsection.vue +34 -10
- package/components/u-td/u-td.vue +28 -0
- package/components/u-tree/tree-node.vue +128 -0
- package/components/u-tree/u-tree.vue +117 -0
- package/components/u-upload/props.js +4 -0
- package/components/u-upload/u-upload.vue +1 -1
- package/components/u-upload/upload.js +2 -1
- package/package.json +1 -1
- package/types/comps/modal.d.ts +1 -1
- package/types/comps/subsection.d.ts +11 -0
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,23 @@
|
|
|
1
|
+
## 3.4.47(2025-07-09)
|
|
2
|
+
fix: 修复datetime-picker打开时,数值可能出现对不上的问题
|
|
3
|
+
|
|
4
|
+
feat: Subsection 分段器添加支持从 list中读取激活文字颜色和未激活文字颜色
|
|
5
|
+
|
|
6
|
+
fix: 修复modal定义confirmButton
|
|
7
|
+
|
|
8
|
+
fix: safe-bottom底部安全距离在小程序优先用JS计算
|
|
9
|
+
|
|
10
|
+
feat: 新增tree树形组件
|
|
11
|
+
|
|
12
|
+
## 3.4.46(2025-07-08)
|
|
13
|
+
feat: 上传组件预览视频支持videoPreviewObjectFit参数
|
|
14
|
+
|
|
15
|
+
feat: td增加多个样式props
|
|
16
|
+
|
|
17
|
+
fix: 修复noticeBar字号增大时文字遮挡
|
|
18
|
+
|
|
19
|
+
feat: 项目工程增加pinia
|
|
20
|
+
|
|
1
21
|
## 3.4.45(2025-07-01)
|
|
2
22
|
fix: 修复picker-data组件缺少name
|
|
3
23
|
|
|
@@ -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
|
},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
})
|
|
@@ -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
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
};
|
package/components/u-td/u-td.vue
CHANGED
|
@@ -25,6 +25,22 @@
|
|
|
25
25
|
width: {
|
|
26
26
|
type: [String],
|
|
27
27
|
default: 'auto'
|
|
28
|
+
},
|
|
29
|
+
textAlign: {
|
|
30
|
+
type: String,
|
|
31
|
+
default: ''
|
|
32
|
+
},
|
|
33
|
+
fontSize: {
|
|
34
|
+
type: String,
|
|
35
|
+
default: ''
|
|
36
|
+
},
|
|
37
|
+
borderColor: {
|
|
38
|
+
type: String,
|
|
39
|
+
default: ''
|
|
40
|
+
},
|
|
41
|
+
color: {
|
|
42
|
+
type: String,
|
|
43
|
+
default: ''
|
|
28
44
|
}
|
|
29
45
|
},
|
|
30
46
|
data() {
|
|
@@ -49,6 +65,18 @@
|
|
|
49
65
|
style.borderBottom = `solid 1px ${this.parent.borderColor}`;
|
|
50
66
|
style.borderRight = `solid 1px ${this.parent.borderColor}`;
|
|
51
67
|
style.color = this.parent.color;
|
|
68
|
+
if (this.textAlign != '') {
|
|
69
|
+
style.textAlign = this.textAlign;
|
|
70
|
+
}
|
|
71
|
+
if (this.fontSize != '') {
|
|
72
|
+
style.fontSize = this.fontSize;
|
|
73
|
+
}
|
|
74
|
+
if (this.borderColor != '') {
|
|
75
|
+
style.borderColor = this.borderColor;
|
|
76
|
+
}
|
|
77
|
+
if (this.color != '') {
|
|
78
|
+
style.color = this.color;
|
|
79
|
+
}
|
|
52
80
|
this.tdStyle = style;
|
|
53
81
|
}
|
|
54
82
|
}
|
|
@@ -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>
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
<video id="myVideo" v-if="popupShow"
|
|
175
175
|
:src="currentItemIndex >= 0 ? lists[currentItemIndex].url : ''"
|
|
176
176
|
@error="videoErrorCallback" show-center-play-btn
|
|
177
|
-
object-fit='
|
|
177
|
+
:object-fit='videoPreviewObjectFit' show-fullscreen-btn='true'
|
|
178
178
|
enable-play-gesture controls
|
|
179
179
|
:autoplay="true" auto-pause-if-open-native
|
|
180
180
|
@loadedmetadata="loadedVideoMetadata"
|
package/package.json
CHANGED
package/types/comps/modal.d.ts
CHANGED
|
@@ -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开始
|