uview-plus 3.8.32 → 3.8.39
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 +2 -0
- package/changelog.md +43 -0
- package/components/u-button/u-button.vue +60 -16
- package/components/u-calendar/calendar.js +4 -3
- package/components/u-calendar/header.vue +74 -32
- package/components/u-calendar/month.vue +9 -0
- package/components/u-calendar/props.js +5 -0
- package/components/u-calendar/u-calendar.vue +46 -0
- package/components/u-input/u-input.vue +3 -1
- package/components/u-parse/node/node.vue +50 -20
- package/components/u-parse/u-parse.vue +38 -8
- package/components/u-tabbar/props.js +35 -0
- package/components/u-tabbar/tabbar.js +8 -1
- package/components/u-tabbar/u-tabbar.vue +82 -4
- package/components/u-tabbar-item/props.js +51 -1
- package/components/u-tabbar-item/tabbarItem.js +11 -1
- package/components/u-tabbar-item/u-tabbar-item.vue +327 -58
- package/index.scss +1 -0
- package/libs/css/theme-legacy-bridge.scss +6 -0
- package/libs/i18n/locales/de.json +1 -0
- package/libs/i18n/locales/en.json +1 -0
- package/libs/i18n/locales/es.json +1 -0
- package/libs/i18n/locales/fr.json +1 -0
- package/libs/i18n/locales/ja.json +1 -0
- package/libs/i18n/locales/ko.json +1 -0
- package/libs/i18n/locales/ru.json +1 -0
- package/libs/i18n/locales/th.json +1 -0
- package/libs/i18n/locales/zh-Hans.json +1 -0
- package/libs/i18n/locales/zh-Hant.json +1 -0
- package/libs/root/LICENSE +21 -0
- package/libs/theme/runtime.js +51 -3
- package/libs/theme/theme.js +7 -8
- package/package.json +1 -1
- package/theme.scss +0 -5
- package/types/comps/calendar.d.ts +5 -0
package/README.md
CHANGED
package/changelog.md
CHANGED
|
@@ -1,3 +1,42 @@
|
|
|
1
|
+
## 3.8.39(2026-05-27)
|
|
2
|
+
feat: 新增 tabbar 风格体系与动态图标表现
|
|
3
|
+
|
|
4
|
+
- 为 tabbar 增加多种内置风格、轻量选中动画与双态图标支持。
|
|
5
|
+
- 扩展示例页覆盖普通场景、NVUE 场景及中间按钮组合用法。
|
|
6
|
+
|
|
7
|
+
## 3.8.38(2026-05-25)
|
|
8
|
+
add: uni-ku/root上游组建的协议原文
|
|
9
|
+
|
|
10
|
+
## 3.8.37(2026-05-22)
|
|
11
|
+
feat: 日历组件新增今天按钮并支持快速回到当月
|
|
12
|
+
|
|
13
|
+
在日历头部增加今天按钮与禁用态,点击后可跳转到今天所在月份;为今天日期增加独立高亮样式且不覆盖用户当前已选日期。同时补充 showToday 配置、类型声明与多语言文案键,保证不同语言和模式下行为一致。
|
|
14
|
+
|
|
15
|
+
## 3.8.36(2026-05-20)
|
|
16
|
+
fix: 修复 u-parse 链接点击在 iOS 端可能闪退的问题
|
|
17
|
+
|
|
18
|
+
- 在 u-parse 的两个链接点击入口统一增加 href 规范化与外链判断,避免空值或非法值传入 plus.runtime.openWeb/openURL。
|
|
19
|
+
- 同时将原生外链打开封装为受保护调用并添加异常兜底,降低 APP-PLUS 与 APP-HARMONY 下点击链接导致崩溃的风险。
|
|
20
|
+
|
|
21
|
+
## 3.8.35(2026-05-19)
|
|
22
|
+
fix: 修复up-input在confirm阶段可能丢失扫码内容
|
|
23
|
+
|
|
24
|
+
- 问题背景:issue #1011 反馈外接扫码枪场景下,up-input 的 confirm 回调偶发丢码,连续0更明显。
|
|
25
|
+
- 原因分析:组件 onConfirm 直接返回 innerValue,当扫码输入与回车触发节奏接近时,confirm 可能早于最后一次 input 同步,导致取到旧值。
|
|
26
|
+
- 改动说明:onConfirm 优先使用 event.detail.value,若平台未提供该字段再回退到 innerValue,兼容原有行为并降低扫码场景丢码风险。
|
|
27
|
+
## 3.8.34(2026-05-18)
|
|
28
|
+
fix: 仅在 TabBar 页面同步 TabBar 样式
|
|
29
|
+
|
|
30
|
+
- 在 libs/theme/runtime.js 新增 isTabBarPage 与 trySetTabBarStyle,统一封装 TabBar 页面判断与安全调用。
|
|
31
|
+
- 在 runtime/theme/common mixin 的原生主题同步路径中,全部改为调用 trySetTabBarStyle,不再直接调用 uni.setTabBarStyle。
|
|
32
|
+
|
|
33
|
+
## 3.8.33(2026-05-17)
|
|
34
|
+
fix: 修复主题变量桥接与 nvue 按钮取色问题
|
|
35
|
+
|
|
36
|
+
- 调整主题 bridge 的导出位置,避免 legacy light 变量在样式注入后覆盖用户自定义 CSS 变量。
|
|
37
|
+
- 修复 up-button 在 nvue 下的主题取色与 info/plain 样式问题,补充运行时取色兜底,避免按钮颜色错误或主题方法缺失时报错。
|
|
38
|
+
- 同步更新示例接入、版本号与变更记录,保持主题改造后的行为与文档一致。
|
|
39
|
+
|
|
1
40
|
## 3.8.32(2026-05-14)
|
|
2
41
|
feat: 新增二维码静区配置
|
|
3
42
|
|
|
@@ -2088,3 +2127,7 @@ fix: #261u-input在直接修改v-model的绑定值时,每隔一次会无法出
|
|
|
2088
2127
|
增加插件市场地址
|
|
2089
2128
|
## 3.0.0(2022-07-09)
|
|
2090
2129
|
# uview-plus(vue3)初步发布
|
|
2130
|
+
## 3.8.39
|
|
2131
|
+
|
|
2132
|
+
- feat: tabbar 新增多种风格预设、动态图标切换与轻量选中动画
|
|
2133
|
+
- improvment: tabbar 补充高颜值本地图标示例并优化发布型底栏视觉
|
|
@@ -117,6 +117,7 @@ import { mixin } from '../../libs/mixin/mixin';
|
|
|
117
117
|
import { props } from "./props";
|
|
118
118
|
import { addStyle } from '../../libs/function/index';
|
|
119
119
|
import { throttle } from '../../libs/function/throttle';
|
|
120
|
+
import { getThemeVar } from '../../libs/theme/runtime.js';
|
|
120
121
|
/**
|
|
121
122
|
* button 按钮
|
|
122
123
|
* @description Button 按钮
|
|
@@ -194,8 +195,43 @@ export default {
|
|
|
194
195
|
isDarkTheme() {
|
|
195
196
|
return this.$u.theme && this.$u.theme.mode === 'dark';
|
|
196
197
|
},
|
|
198
|
+
nvueMainColor() {
|
|
199
|
+
return this.resolveNvueColor(this.$u.color.mainColor, this.isDarkTheme ? '#f5f5f5' : '#303133');
|
|
200
|
+
},
|
|
201
|
+
nvueBorderColor() {
|
|
202
|
+
return this.resolveNvueColor(this.$u.color.borderColor, this.isDarkTheme ? '#3a3a3c' : '#dadbde');
|
|
203
|
+
},
|
|
197
204
|
themeTypeColor() {
|
|
198
|
-
|
|
205
|
+
const fallbackMap = {
|
|
206
|
+
primary: '#3c9cff',
|
|
207
|
+
success: '#5ac725',
|
|
208
|
+
warning: '#f9ae3d',
|
|
209
|
+
error: '#f56c6c',
|
|
210
|
+
info: '#909399',
|
|
211
|
+
};
|
|
212
|
+
const type = fallbackMap[this.type] ? this.type : 'info';
|
|
213
|
+
return this.resolveNvueColor(
|
|
214
|
+
this.upThemeVar(`--up-${type}`, fallbackMap[type]),
|
|
215
|
+
fallbackMap[type]
|
|
216
|
+
);
|
|
217
|
+
},
|
|
218
|
+
nvueInfoBackgroundColor() {
|
|
219
|
+
return this.upThemeVar(
|
|
220
|
+
'--up-button-info-background-color',
|
|
221
|
+
this.upThemeVar(
|
|
222
|
+
'--up-card-bg-color',
|
|
223
|
+
this.isDarkTheme ? '#1c1c1e' : '#ffffff'
|
|
224
|
+
)
|
|
225
|
+
);
|
|
226
|
+
},
|
|
227
|
+
nvuePlainBackgroundColor() {
|
|
228
|
+
return this.upThemeVar(
|
|
229
|
+
'--up-button-plain-background-color',
|
|
230
|
+
this.upThemeVar(
|
|
231
|
+
'--up-card-bg-color',
|
|
232
|
+
this.isDarkTheme ? '#1c1c1e' : '#ffffff'
|
|
233
|
+
)
|
|
234
|
+
);
|
|
199
235
|
},
|
|
200
236
|
loadingColor() {
|
|
201
237
|
if (this.plain) {
|
|
@@ -212,13 +248,11 @@ export default {
|
|
|
212
248
|
iconColorCom() {
|
|
213
249
|
// 如果是镂空状态,设置了color就用color值,否则使用主题颜色,
|
|
214
250
|
// up-icon的color能接受一个主题颜色的值
|
|
215
|
-
|
|
251
|
+
if (this.iconColor) return this.iconColor;
|
|
216
252
|
if (this.plain) {
|
|
217
253
|
return this.color ? this.color : this.type;
|
|
218
254
|
} else {
|
|
219
|
-
return this.type === "info"
|
|
220
|
-
? (this.isDarkTheme ? "#f3f4f6" : "#000000")
|
|
221
|
-
: "#ffffff";
|
|
255
|
+
return this.type === "info" ? this.nvueMainColor : "#ffffff";
|
|
222
256
|
}
|
|
223
257
|
},
|
|
224
258
|
baseColor() {
|
|
@@ -249,26 +283,28 @@ export default {
|
|
|
249
283
|
}
|
|
250
284
|
return style;
|
|
251
285
|
}
|
|
286
|
+
// #ifdef APP-NVUE
|
|
252
287
|
const typeColor = this.themeTypeColor;
|
|
253
288
|
if (this.plain) {
|
|
254
|
-
style.color = this.type === 'info' ? this
|
|
255
|
-
style.backgroundColor = this.
|
|
256
|
-
style.borderColor = this.type === 'info' ? this
|
|
289
|
+
style.color = this.type === 'info' ? this.nvueMainColor : typeColor;
|
|
290
|
+
style.backgroundColor = this.nvuePlainBackgroundColor;
|
|
291
|
+
style.borderColor = this.type === 'info' ? this.nvueBorderColor : typeColor;
|
|
257
292
|
style.borderWidth = this.hairline ? '0.5px' : '1px';
|
|
258
293
|
style.borderStyle = 'solid';
|
|
259
294
|
} else {
|
|
260
295
|
style.borderWidth = this.hairline ? '0.5px' : '1px';
|
|
261
296
|
style.borderStyle = 'solid';
|
|
262
297
|
if (this.type === 'info') {
|
|
263
|
-
style.color = this
|
|
264
|
-
style.backgroundColor = this.
|
|
265
|
-
style.borderColor = this
|
|
298
|
+
style.color = this.nvueMainColor;
|
|
299
|
+
style.backgroundColor = this.nvueInfoBackgroundColor;
|
|
300
|
+
style.borderColor = this.nvueBorderColor;
|
|
266
301
|
} else {
|
|
267
302
|
style.color = '#ffffff';
|
|
268
303
|
style.backgroundColor = typeColor;
|
|
269
304
|
style.borderColor = typeColor;
|
|
270
305
|
}
|
|
271
306
|
}
|
|
307
|
+
// #endif
|
|
272
308
|
return style;
|
|
273
309
|
},
|
|
274
310
|
// nvue版本按钮的字体不会继承父组件的颜色,需要对每一个text组件进行单独的设置
|
|
@@ -276,7 +312,7 @@ export default {
|
|
|
276
312
|
let style = {};
|
|
277
313
|
// 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
|
|
278
314
|
if (this.type === "info") {
|
|
279
|
-
style.color = this
|
|
315
|
+
style.color = this.nvueMainColor;
|
|
280
316
|
}
|
|
281
317
|
if (this.color) {
|
|
282
318
|
style.color = this.plain ? this.color : "white";
|
|
@@ -301,6 +337,14 @@ export default {
|
|
|
301
337
|
'error', 'opensetting', 'launchapp', 'agreeprivacyauthorization'],
|
|
302
338
|
methods: {
|
|
303
339
|
addStyle,
|
|
340
|
+
resolveNvueColor(colorValue, fallbackColor) {
|
|
341
|
+
if (typeof colorValue !== 'string') return fallbackColor;
|
|
342
|
+
if (colorValue.indexOf('var(') > -1) return fallbackColor;
|
|
343
|
+
return colorValue;
|
|
344
|
+
},
|
|
345
|
+
upThemeVar(varName, fallbackColor) {
|
|
346
|
+
return getThemeVar(varName, fallbackColor, this.$u);
|
|
347
|
+
},
|
|
304
348
|
clickHandler(e: any) {
|
|
305
349
|
// 非禁止并且非加载中,才能点击
|
|
306
350
|
if (!this.disabled && !this.loading) {
|
|
@@ -362,9 +406,9 @@ $u-button-mini-height: 22px !default;
|
|
|
362
406
|
$u-button-mini-font-size: 10px !default;
|
|
363
407
|
$u-button-mini-min-width: 50px !default;
|
|
364
408
|
$u-button-disabled-opacity: 0.5 !default;
|
|
365
|
-
$u-button-info-color:
|
|
366
|
-
$u-button-info-background-color: #fff !default;
|
|
367
|
-
$u-button-info-border-color:
|
|
409
|
+
$u-button-info-color: $u-main-color !default;
|
|
410
|
+
$u-button-info-background-color: var(--up-button-info-background-color, var(--up-card-bg-color, #fff)) !default;
|
|
411
|
+
$u-button-info-border-color: $u-border-color !default;
|
|
368
412
|
$u-button-info-border-width: 1px !default;
|
|
369
413
|
$u-button-info-border-style: solid !default;
|
|
370
414
|
$u-button-success-color: #fff !default;
|
|
@@ -397,7 +441,7 @@ $u-button-square-border-top-left-radius: 3px !default;
|
|
|
397
441
|
$u-button-square-border-bottom-left-radius: 3px !default;
|
|
398
442
|
$u-button-square-border-bottom-right-radius: 3px !default;
|
|
399
443
|
$u-button-icon-min-width: 1em !default;
|
|
400
|
-
$u-button-plain-background-color: #fff !default;
|
|
444
|
+
$u-button-plain-background-color: var(--up-button-plain-background-color, var(--up-card-bg-color, #fff)) !default;
|
|
401
445
|
$u-button-hairline-border-width: 0.5px !default;
|
|
402
446
|
|
|
403
447
|
.u-button {
|
|
@@ -38,9 +38,10 @@ export default {
|
|
|
38
38
|
showRangePrompt: true,
|
|
39
39
|
allowSameDay: false,
|
|
40
40
|
round: 0,
|
|
41
|
-
monthNum: 3,
|
|
42
|
-
monthSwitch: false,
|
|
43
|
-
|
|
41
|
+
monthNum: 3,
|
|
42
|
+
monthSwitch: false,
|
|
43
|
+
showToday: true,
|
|
44
|
+
weekText: [t("up.week.one"), t("up.week.two"), t("up.week.three"), t("up.week.four"), t("up.week.five"), t("up.week.six"), t("up.week.seven")],
|
|
44
45
|
forbidDays: [],
|
|
45
46
|
forbidDaysToast: t("up.calendar.disabled"),
|
|
46
47
|
monthFormat: '',
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
class="u-calendar-header__title"
|
|
5
5
|
v-if="showTitle"
|
|
6
6
|
>{{ title }}</text>
|
|
7
|
-
<view
|
|
8
|
-
class="u-calendar-header__subtitle-wrap"
|
|
9
|
-
v-if="showSubtitle"
|
|
10
|
-
>
|
|
7
|
+
<view
|
|
8
|
+
class="u-calendar-header__subtitle-wrap"
|
|
9
|
+
v-if="showSubtitle"
|
|
10
|
+
>
|
|
11
11
|
<text
|
|
12
12
|
v-if="showSwitch"
|
|
13
13
|
class="u-calendar-header__switch"
|
|
@@ -27,13 +27,19 @@
|
|
|
27
27
|
:class="{ 'u-calendar-header__switch--disabled': nextDisabled }"
|
|
28
28
|
@click="next"
|
|
29
29
|
>›</text>
|
|
30
|
-
<text
|
|
31
|
-
v-if="showSwitch"
|
|
32
|
-
class="u-calendar-header__switch"
|
|
33
|
-
:class="{ 'u-calendar-header__switch--disabled': nextYearDisabled }"
|
|
34
|
-
@click="nextYear"
|
|
35
|
-
>»</text>
|
|
36
|
-
|
|
30
|
+
<text
|
|
31
|
+
v-if="showSwitch"
|
|
32
|
+
class="u-calendar-header__switch"
|
|
33
|
+
:class="{ 'u-calendar-header__switch--disabled': nextYearDisabled }"
|
|
34
|
+
@click="nextYear"
|
|
35
|
+
>»</text>
|
|
36
|
+
<text
|
|
37
|
+
v-if="showToday"
|
|
38
|
+
class="u-calendar-header__today"
|
|
39
|
+
:class="{ 'u-calendar-header__today--disabled': todayDisabled }"
|
|
40
|
+
@click="today"
|
|
41
|
+
>{{ todayText }}</text>
|
|
42
|
+
</view>
|
|
37
43
|
<view class="u-calendar-header__weekdays">
|
|
38
44
|
<text class="u-calendar-header__weekdays__weekday">{{ weekText[0] }}</text>
|
|
39
45
|
<text class="u-calendar-header__weekdays__weekday">{{ weekText[1] }}</text>
|
|
@@ -100,12 +106,27 @@
|
|
|
100
106
|
type: Boolean,
|
|
101
107
|
default: false
|
|
102
108
|
},
|
|
103
|
-
// 下一年按钮是否禁用
|
|
104
|
-
nextYearDisabled: {
|
|
105
|
-
type: Boolean,
|
|
106
|
-
default: false
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
+
// 下一年按钮是否禁用
|
|
110
|
+
nextYearDisabled: {
|
|
111
|
+
type: Boolean,
|
|
112
|
+
default: false
|
|
113
|
+
},
|
|
114
|
+
// 是否显示今天按钮
|
|
115
|
+
showToday: {
|
|
116
|
+
type: Boolean,
|
|
117
|
+
default: true
|
|
118
|
+
},
|
|
119
|
+
// 今天按钮文案
|
|
120
|
+
todayText: {
|
|
121
|
+
type: String,
|
|
122
|
+
default: ''
|
|
123
|
+
},
|
|
124
|
+
// 今天按钮是否禁用
|
|
125
|
+
todayDisabled: {
|
|
126
|
+
type: Boolean,
|
|
127
|
+
default: false
|
|
128
|
+
}
|
|
129
|
+
},
|
|
109
130
|
data() {
|
|
110
131
|
return {
|
|
111
132
|
|
|
@@ -127,13 +148,18 @@
|
|
|
127
148
|
this.$emit('prevYear')
|
|
128
149
|
}
|
|
129
150
|
},
|
|
130
|
-
nextYear() {
|
|
131
|
-
if (!this.nextYearDisabled) {
|
|
132
|
-
this.$emit('nextYear')
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
151
|
+
nextYear() {
|
|
152
|
+
if (!this.nextYearDisabled) {
|
|
153
|
+
this.$emit('nextYear')
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
today() {
|
|
157
|
+
if (!this.todayDisabled) {
|
|
158
|
+
this.$emit('today')
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
}
|
|
137
163
|
</script>
|
|
138
164
|
|
|
139
165
|
<style lang="scss" scoped>
|
|
@@ -182,17 +208,33 @@
|
|
|
182
208
|
}
|
|
183
209
|
}
|
|
184
210
|
|
|
185
|
-
&__weekdays {
|
|
186
|
-
@include flex;
|
|
187
|
-
justify-content: space-between;
|
|
211
|
+
&__weekdays {
|
|
212
|
+
@include flex;
|
|
213
|
+
justify-content: space-between;
|
|
188
214
|
|
|
189
215
|
&__weekday {
|
|
190
216
|
font-size: 13px;
|
|
191
217
|
color: var(--up-main-color, $u-main-color);
|
|
192
218
|
line-height: 30px;
|
|
193
219
|
flex: 1;
|
|
194
|
-
text-align: center;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
|
|
220
|
+
text-align: center;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
&__today {
|
|
225
|
+
margin-left: 4px;
|
|
226
|
+
height: 28px;
|
|
227
|
+
line-height: 28px;
|
|
228
|
+
padding: 0 10px;
|
|
229
|
+
border-radius: 14px;
|
|
230
|
+
font-size: 13px;
|
|
231
|
+
color: var(--up-primary, $u-primary);
|
|
232
|
+
border: 1px solid var(--up-primary, $u-primary);
|
|
233
|
+
flex-shrink: 0;
|
|
234
|
+
|
|
235
|
+
&--disabled {
|
|
236
|
+
opacity: 0.35;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
</style>
|
|
@@ -135,6 +135,11 @@
|
|
|
135
135
|
forbidDaysToast: {
|
|
136
136
|
type: String,
|
|
137
137
|
default: ''
|
|
138
|
+
},
|
|
139
|
+
// 今天日期,用于独立高亮
|
|
140
|
+
todayDate: {
|
|
141
|
+
type: String,
|
|
142
|
+
default: ''
|
|
138
143
|
}
|
|
139
144
|
},
|
|
140
145
|
data() {
|
|
@@ -193,6 +198,10 @@
|
|
|
193
198
|
if (this.selected.some(item => this.dateSame(item, date))) {
|
|
194
199
|
style.backgroundColor = this.color
|
|
195
200
|
}
|
|
201
|
+
if (this.todayDate && this.dateSame(date, this.todayDate) && !this.selected.some(item => this.dateSame(item, date))) {
|
|
202
|
+
style.border = `1px solid ${this.color}`
|
|
203
|
+
style.boxSizing = 'border-box'
|
|
204
|
+
}
|
|
196
205
|
if (this.mode === 'single') {
|
|
197
206
|
if (date === this.selected[0]) {
|
|
198
207
|
// 因为需要对nvue的兼容,只能这么写,无法缩写,也无法通过类名控制等等
|
|
@@ -148,6 +148,11 @@ export const props = defineMixin({
|
|
|
148
148
|
type: Boolean,
|
|
149
149
|
default: () => defProps.calendar.monthSwitch
|
|
150
150
|
},
|
|
151
|
+
// 是否显示今天按钮
|
|
152
|
+
showToday: {
|
|
153
|
+
type: Boolean,
|
|
154
|
+
default: () => defProps.calendar.showToday
|
|
155
|
+
},
|
|
151
156
|
// 星期文案
|
|
152
157
|
weekText: {
|
|
153
158
|
type: Array,
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
:showTitle="showTitle"
|
|
17
17
|
:weekText="weekText"
|
|
18
18
|
:showSwitch="monthSwitch"
|
|
19
|
+
:showToday="showToday"
|
|
20
|
+
:todayText="todayText"
|
|
21
|
+
:todayDisabled="todayDisabled"
|
|
19
22
|
:prevDisabled="switchPrevDisabled"
|
|
20
23
|
:nextDisabled="switchNextDisabled"
|
|
21
24
|
:prevYearDisabled="switchPrevYearDisabled"
|
|
@@ -24,6 +27,7 @@
|
|
|
24
27
|
@next="nextMonth"
|
|
25
28
|
@prevYear="prevYear"
|
|
26
29
|
@nextYear="nextYear"
|
|
30
|
+
@today="jumpToToday"
|
|
27
31
|
></uHeader>
|
|
28
32
|
<scroll-view
|
|
29
33
|
v-if="!monthSwitch"
|
|
@@ -56,6 +60,7 @@
|
|
|
56
60
|
:forbidDays="forbidDays"
|
|
57
61
|
:forbidDaysToast="forbidDaysToast"
|
|
58
62
|
:monthFormat="monthFormat"
|
|
63
|
+
:todayDate="todayDate"
|
|
59
64
|
ref="month"
|
|
60
65
|
@monthSelected="monthSelected"
|
|
61
66
|
@updateMonthTop="onUpdateMonthTop"
|
|
@@ -88,6 +93,7 @@
|
|
|
88
93
|
:forbidDays="forbidDays"
|
|
89
94
|
:forbidDaysToast="forbidDaysToast"
|
|
90
95
|
:monthFormat="monthFormat"
|
|
96
|
+
:todayDate="todayDate"
|
|
91
97
|
ref="month"
|
|
92
98
|
@monthSelected="monthSelected"
|
|
93
99
|
@updateMonthTop="onUpdateMonthTop"
|
|
@@ -121,6 +127,7 @@ import { mpMixin } from '../../libs/mixin/mpMixin.js'
|
|
|
121
127
|
import { mixin } from '../../libs/mixin/mixin.js'
|
|
122
128
|
import { addUnit, getPx, range, error, padZero } from '../../libs/function/index';
|
|
123
129
|
import test from '../../libs/function/test';
|
|
130
|
+
import { t } from '../../libs/i18n'
|
|
124
131
|
/**
|
|
125
132
|
* Calendar 日历
|
|
126
133
|
* @description 此组件用于单个选择日期,范围选择日期等,日历被包裹在底部弹起的容器中.
|
|
@@ -224,6 +231,28 @@ export default {
|
|
|
224
231
|
? Number(this.minDate)
|
|
225
232
|
: this.minDate
|
|
226
233
|
},
|
|
234
|
+
todayDate() {
|
|
235
|
+
return dayjs().format('YYYY-MM-DD')
|
|
236
|
+
},
|
|
237
|
+
todayText() {
|
|
238
|
+
return t('up.calendar.today')
|
|
239
|
+
},
|
|
240
|
+
todayDisabled() {
|
|
241
|
+
const today = dayjs(this.todayDate)
|
|
242
|
+
const minDate = this.innerMinDate
|
|
243
|
+
? dayjs(this.innerMinDate)
|
|
244
|
+
: null
|
|
245
|
+
const maxDate = this.innerMaxDate
|
|
246
|
+
? dayjs(this.innerMaxDate)
|
|
247
|
+
: null
|
|
248
|
+
if (minDate && today.isBefore(minDate, 'day')) {
|
|
249
|
+
return true
|
|
250
|
+
}
|
|
251
|
+
if (maxDate && today.isAfter(maxDate, 'day')) {
|
|
252
|
+
return true
|
|
253
|
+
}
|
|
254
|
+
return false
|
|
255
|
+
},
|
|
227
256
|
// 多个条件的变化,会引起选中日期的变化,这里统一管理监听
|
|
228
257
|
selectedChange() {
|
|
229
258
|
return [this.innerMinDate, this.innerMaxDate, this.defaultDate]
|
|
@@ -449,6 +478,22 @@ export default {
|
|
|
449
478
|
this.monthIndex += 12
|
|
450
479
|
}
|
|
451
480
|
},
|
|
481
|
+
jumpToToday() {
|
|
482
|
+
if (this.todayDisabled) {
|
|
483
|
+
return
|
|
484
|
+
}
|
|
485
|
+
const targetMonth = dayjs(this.todayDate).format('YYYY-MM')
|
|
486
|
+
if (this.monthSwitch) {
|
|
487
|
+
const todayMonthIndex = this.months.findIndex(({ year, month }) => {
|
|
488
|
+
return `${year}-${padZero(month)}` === targetMonth
|
|
489
|
+
})
|
|
490
|
+
if (todayMonthIndex !== -1) {
|
|
491
|
+
this.monthIndex = todayMonthIndex
|
|
492
|
+
}
|
|
493
|
+
return
|
|
494
|
+
}
|
|
495
|
+
this.scrollIntoDefaultMonth(targetMonth)
|
|
496
|
+
},
|
|
452
497
|
// 滚动到默认设置的月份
|
|
453
498
|
scrollIntoDefaultMonth(selected) {
|
|
454
499
|
// 查询默认日期在可选列表的下标
|
|
@@ -462,6 +507,7 @@ export default {
|
|
|
462
507
|
if (_index !== -1) {
|
|
463
508
|
// #ifndef MP-WEIXIN
|
|
464
509
|
this.$nextTick(() => {
|
|
510
|
+
this.scrollIntoView = ''
|
|
465
511
|
this.scrollIntoView = `month-${_index}`
|
|
466
512
|
this.scrollIntoViewScroll = this.scrollIntoView
|
|
467
513
|
})
|
|
@@ -324,7 +324,9 @@ export default {
|
|
|
324
324
|
},
|
|
325
325
|
// 点击完成按钮时触发
|
|
326
326
|
onConfirm(event) {
|
|
327
|
-
|
|
327
|
+
const detail = event && event.detail ? event.detail : {};
|
|
328
|
+
const confirmValue = typeof detail.value !== "undefined" ? detail.value : this.innerValue;
|
|
329
|
+
this.$emit("confirm", confirmValue);
|
|
328
330
|
},
|
|
329
331
|
// 键盘高度发生变化的时候触发此事件
|
|
330
332
|
// 兼容性:微信小程序2.7.0+、App 3.1.0+
|
|
@@ -185,6 +185,53 @@ export default {
|
|
|
185
185
|
// #ifdef MP-WEIXIN
|
|
186
186
|
toJSON () { return this },
|
|
187
187
|
// #endif
|
|
188
|
+
/**
|
|
189
|
+
* @description 规范化链接地址
|
|
190
|
+
* @param {any} href
|
|
191
|
+
* @return {String}
|
|
192
|
+
*/
|
|
193
|
+
normalizeHref (href) {
|
|
194
|
+
return typeof href === 'string' ? href.trim() : ''
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @description 判断是否为外部链接
|
|
199
|
+
* @param {String} href
|
|
200
|
+
* @return {Boolean}
|
|
201
|
+
*/
|
|
202
|
+
isExternalLink (href) {
|
|
203
|
+
return href.split('?')[0].includes('://')
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* @description 打开外部链接
|
|
208
|
+
* @param {String} href
|
|
209
|
+
*/
|
|
210
|
+
openExternalLink (href) {
|
|
211
|
+
// #ifdef H5
|
|
212
|
+
window.open(href)
|
|
213
|
+
// #endif
|
|
214
|
+
// #ifdef MP
|
|
215
|
+
uni.setClipboardData({
|
|
216
|
+
data: href,
|
|
217
|
+
success: () =>
|
|
218
|
+
uni.showToast({
|
|
219
|
+
title: '链接已复制'
|
|
220
|
+
})
|
|
221
|
+
})
|
|
222
|
+
// #endif
|
|
223
|
+
// #ifdef APP-PLUS
|
|
224
|
+
try {
|
|
225
|
+
plus.runtime.openWeb(href)
|
|
226
|
+
} catch (e) { }
|
|
227
|
+
// #endif
|
|
228
|
+
// #ifdef APP-HARMONY
|
|
229
|
+
try {
|
|
230
|
+
plus.runtime.openURL(href)
|
|
231
|
+
} catch (e) { }
|
|
232
|
+
// #endif
|
|
233
|
+
},
|
|
234
|
+
|
|
188
235
|
/**
|
|
189
236
|
* @description 播放视频事件
|
|
190
237
|
* @param {Event} e
|
|
@@ -341,7 +388,7 @@ export default {
|
|
|
341
388
|
linkTap (e) {
|
|
342
389
|
const node = e.currentTarget ? this.childs[e.currentTarget.dataset.i] : {}
|
|
343
390
|
const attrs = node.attrs || e
|
|
344
|
-
const href = attrs.href
|
|
391
|
+
const href = this.normalizeHref(attrs.href)
|
|
345
392
|
this.root.$emit('linktap', Object.assign({
|
|
346
393
|
innerText: this.root.getText(node.children || []) // 链接内的文本内容
|
|
347
394
|
}, attrs))
|
|
@@ -349,27 +396,10 @@ export default {
|
|
|
349
396
|
if (href[0] === '#') {
|
|
350
397
|
// 跳转锚点
|
|
351
398
|
this.root.navigateTo(href.substring(1)).catch(() => { })
|
|
352
|
-
} else if (
|
|
399
|
+
} else if (this.isExternalLink(href)) {
|
|
353
400
|
// 复制外部链接
|
|
354
401
|
if (this.root.copyLink) {
|
|
355
|
-
|
|
356
|
-
window.open(href)
|
|
357
|
-
// #endif
|
|
358
|
-
// #ifdef MP
|
|
359
|
-
uni.setClipboardData({
|
|
360
|
-
data: href,
|
|
361
|
-
success: () =>
|
|
362
|
-
uni.showToast({
|
|
363
|
-
title: '链接已复制'
|
|
364
|
-
})
|
|
365
|
-
})
|
|
366
|
-
// #endif
|
|
367
|
-
// #ifdef APP-PLUS
|
|
368
|
-
plus.runtime.openWeb(href)
|
|
369
|
-
// #endif
|
|
370
|
-
// #ifdef APP-HARMONY
|
|
371
|
-
plus.runtime.openURL(href)
|
|
372
|
-
// #endif
|
|
402
|
+
this.openExternalLink(href)
|
|
373
403
|
}
|
|
374
404
|
} else {
|
|
375
405
|
// 跳转页面
|
|
@@ -130,6 +130,41 @@ export default {
|
|
|
130
130
|
this._hook('onDetached')
|
|
131
131
|
},
|
|
132
132
|
methods: {
|
|
133
|
+
/**
|
|
134
|
+
* @description 规范化链接地址
|
|
135
|
+
* @param {any} href
|
|
136
|
+
* @return {String}
|
|
137
|
+
*/
|
|
138
|
+
normalizeHref(href) {
|
|
139
|
+
return typeof href === 'string' ? href.trim() : ''
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @description 判断是否为外部链接
|
|
144
|
+
* @param {String} href
|
|
145
|
+
* @return {Boolean}
|
|
146
|
+
*/
|
|
147
|
+
isExternalLink(href) {
|
|
148
|
+
return href.split('?')[0].includes('://')
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @description 打开外部链接
|
|
153
|
+
* @param {String} href
|
|
154
|
+
*/
|
|
155
|
+
openExternalLink(href) {
|
|
156
|
+
// #ifdef APP-PLUS
|
|
157
|
+
try {
|
|
158
|
+
plus.runtime.openWeb(href)
|
|
159
|
+
} catch (e) { }
|
|
160
|
+
// #endif
|
|
161
|
+
// #ifdef APP-HARMONY
|
|
162
|
+
try {
|
|
163
|
+
plus.runtime.openURL(href)
|
|
164
|
+
} catch (e) { }
|
|
165
|
+
// #endif
|
|
166
|
+
},
|
|
167
|
+
|
|
133
168
|
/**
|
|
134
169
|
* @description 将锚点跳转的范围限定在一个 scroll-view 内
|
|
135
170
|
* @param {Object} page scroll-view 所在页面的示例
|
|
@@ -420,7 +455,7 @@ export default {
|
|
|
420
455
|
break
|
|
421
456
|
// 链接点击
|
|
422
457
|
case 'onLinkTap': {
|
|
423
|
-
const href = message.attrs.href
|
|
458
|
+
const href = this.normalizeHref(message.attrs.href)
|
|
424
459
|
this.$emit('linktap', message.attrs)
|
|
425
460
|
if (href) {
|
|
426
461
|
// 锚点跳转
|
|
@@ -430,15 +465,10 @@ export default {
|
|
|
430
465
|
offset: message.offset
|
|
431
466
|
})
|
|
432
467
|
}
|
|
433
|
-
} else if (
|
|
468
|
+
} else if (this.isExternalLink(href)) {
|
|
434
469
|
// 打开外链
|
|
435
470
|
if (this.copyLink) {
|
|
436
|
-
|
|
437
|
-
plus.runtime.openWeb(href)
|
|
438
|
-
// #endif
|
|
439
|
-
// #ifdef APP-HARMONY
|
|
440
|
-
plus.runtime.openURL(href)
|
|
441
|
-
// #endif
|
|
471
|
+
this.openExternalLink(href)
|
|
442
472
|
}
|
|
443
473
|
} else {
|
|
444
474
|
uni.navigateTo({
|