uview-plus 3.8.86 → 3.8.106
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 +150 -3
- package/components/u-action-sheet/u-action-sheet.vue +21 -2
- package/components/u-barcode/u-barcode.vue +0 -2
- package/components/u-button/u-button.vue +2 -5
- package/components/u-canvas/u-canvas.vue +368 -74
- package/components/u-cell/u-cell.vue +8 -0
- package/components/u-datetime-picker/u-datetime-picker.vue +53 -4
- package/components/u-dragsort/u-dragsort.vue +55 -31
- package/components/u-icon/u-icon.vue +12 -3
- package/components/u-icon/util.js +81 -10
- package/components/u-index-item/u-index-item.vue +1 -1
- package/components/u-index-list/u-index-list.vue +1 -1
- package/components/u-novel-reader/content-normalizer.js +80 -0
- package/components/u-novel-reader/layout-engine.js +225 -0
- package/components/u-novel-reader/measure-adapter.js +69 -0
- package/components/u-novel-reader/novelReader.js +35 -0
- package/components/u-novel-reader/persistence.js +144 -0
- package/components/u-novel-reader/props.js +100 -0
- package/components/u-novel-reader/reader-catalog.vue +234 -0
- package/components/u-novel-reader/reader-content.vue +226 -0
- package/components/u-novel-reader/reader-core.js +151 -0
- package/components/u-novel-reader/reader-settings.vue +325 -0
- package/components/u-novel-reader/reader-toolbar.vue +313 -0
- package/components/u-novel-reader/theme-vars.scss +49 -0
- package/components/u-novel-reader/u-novel-reader.vue +836 -0
- package/components/u-poster/u-poster.vue +236 -219
- package/components/u-qrcode/qrcode.js +56 -49
- package/components/u-qrcode/u-qrcode.vue +159 -88
- package/components/u-scroll-list/scrollWxs.wxs +1 -1
- package/components/u-slider/u-slider.vue +1 -1
- package/components/u-swipe-action-item/index.wxs +43 -25
- package/components/u-swipe-action-item/nvue.js +9 -0
- package/components/u-swipe-action-item/other.js +32 -21
- package/components/u-swipe-action-item/props.js +5 -0
- package/components/u-swipe-action-item/swipeActionItem.js +1 -0
- package/components/u-swipe-action-item/u-swipe-action-item.vue +28 -4
- package/components/u-switch/u-switch.vue +1 -1
- package/components/u-tabbar/u-tabbar.vue +2 -1
- package/components/u-tabbar-item/u-tabbar-item.vue +64 -21
- package/components/u-tabs/u-tabs.vue +11 -8
- package/components/u-tabs-pro/u-tabs-pro.vue +212 -0
- package/components/u-text/text.js +1 -1
- package/components/u-text/u-text.vue +18 -6
- package/components/u-upload/u-upload.vue +1 -1
- package/components/u-waterfall/u-waterfall.vue +118 -65
- package/libs/config/config.js +1 -1
- package/libs/config/props.js +1 -0
- package/libs/function/index.js +66 -0
- package/libs/mixin/mixin.js +4 -50
- package/libs/root/index.js +78 -5
- package/libs/root/page.js +7 -7
- package/libs/root/root.js +73 -3
- package/libs/util/app-nvue-webview-canvas.js +486 -0
- package/libs/util/gcanvas/bridge/bridge-weex.js +0 -2
- package/libs/util/gcanvas/context-2d/FillStyleLinearGradient.js +0 -0
- package/libs/util/gcanvas/context-2d/FillStylePattern.js +0 -0
- package/libs/util/gcanvas/context-2d/FillStyleRadialGradient.js +0 -0
- package/libs/util/gcanvas/context-2d/RenderingContext.js +0 -0
- package/libs/util/gcanvas/context-webgl/ActiveInfo.js +0 -0
- package/libs/util/gcanvas/context-webgl/Buffer.js +0 -0
- package/libs/util/gcanvas/context-webgl/Framebuffer.js +0 -0
- package/libs/util/gcanvas/context-webgl/GLenum.js +0 -0
- package/libs/util/gcanvas/context-webgl/GLmethod.js +0 -0
- package/libs/util/gcanvas/context-webgl/GLtype.js +0 -0
- package/libs/util/gcanvas/context-webgl/Program.js +0 -0
- package/libs/util/gcanvas/context-webgl/Renderbuffer.js +0 -0
- package/libs/util/gcanvas/context-webgl/RenderingContext.js +0 -0
- package/libs/util/gcanvas/context-webgl/Shader.js +0 -0
- package/libs/util/gcanvas/context-webgl/ShaderPrecisionFormat.js +0 -0
- package/libs/util/gcanvas/context-webgl/Texture.js +0 -0
- package/libs/util/gcanvas/context-webgl/UniformLocation.js +0 -0
- package/libs/util/gcanvas/context-webgl/classUtils.js +0 -0
- package/libs/util/gcanvas/env/canvas.js +0 -0
- package/libs/util/gcanvas/env/image.js +0 -0
- package/libs/util/gcanvas/env/tool.js +0 -0
- package/libs/util/gcanvas/index.js +3 -3
- package/package.json +1 -1
- package/types/comps/swipeActionItem.d.ts +13 -0
- package/types/comps/tabs.d.ts +2 -1
- package/types/comps/text.d.ts +1 -1
- package/types/func.d.ts +23 -0
- package/types/index.d.ts +1 -0
|
@@ -32,14 +32,14 @@
|
|
|
32
32
|
</view>
|
|
33
33
|
<!-- #ifdef APP-VUE || MP-WEIXIN || MP-QQ || H5 -->
|
|
34
34
|
<view class="u-swipe-action-item__content" @touchstart="wxs.touchstart" @touchmove="wxs.touchmove"
|
|
35
|
-
@touchend="wxs.touchend" :status="status" :change:status="wxs.statusChange" :size="size"
|
|
35
|
+
@touchend="wxs.touchend" @touchcancel="wxs.touchcancel" :status="status" :change:status="wxs.statusChange" :size="size"
|
|
36
36
|
:change:size="wxs.sizeChange">
|
|
37
37
|
<slot></slot>
|
|
38
38
|
</view>
|
|
39
39
|
<!-- #endif -->
|
|
40
40
|
<!-- #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO-->
|
|
41
41
|
<view class="u-swipe-action-item__content" @click="clickHandler" @touchstart="touchstart" @touchmove="touchmove"
|
|
42
|
-
@touchend="touchend" :style="sliderStyle">
|
|
42
|
+
@touchend="touchend" @touchcancel="touchcancel" :style="sliderStyle">
|
|
43
43
|
<slot></slot>
|
|
44
44
|
</view>
|
|
45
45
|
<!-- <view class="u-swipe-action-item__content" @touchstart="mysjs.touchstart" @touchmove="mysjs.touchmove"
|
|
@@ -81,16 +81,18 @@
|
|
|
81
81
|
* @property {String | Number} index 标识符,如果是v-for,可用index索引
|
|
82
82
|
* @property {Boolean} disabled 是否禁用(默认 false )
|
|
83
83
|
* @property {Boolean} autoClose 是否自动关闭其他swipe按钮组(默认 true )
|
|
84
|
+
* @property {Boolean} scrolling 是否正在横向滑动,可用于v-model:scrolling暂停外部滚动(默认 false )
|
|
84
85
|
* @property {Number} threshold 滑动距离阈值,只有大于此值,才被认为是要打开菜单(默认 30 )
|
|
85
86
|
* @property {Array} options 右侧按钮内容
|
|
86
87
|
* @property {String | Number} duration 动画过渡时间,单位ms(默认 350 )
|
|
88
|
+
* @event {Function(value)} scrolling 横向滑动状态变化时触发,参数为Boolean
|
|
87
89
|
* @event {Function(index)} open 组件打开时触发
|
|
88
90
|
* @event {Function(index)} close 组件关闭时触发
|
|
89
91
|
* @example <u-swipe-action><u-swipe-action-item :options="options1" ></u-swipe-action-item></u-swipe-action>
|
|
90
92
|
*/
|
|
91
93
|
export default {
|
|
92
94
|
name: 'u-swipe-action-item',
|
|
93
|
-
emits: ['click', 'update:show'],
|
|
95
|
+
emits: ['click', 'update:show', 'update:scrolling', 'scrolling'],
|
|
94
96
|
mixins: [
|
|
95
97
|
mpMixin,
|
|
96
98
|
mixin,
|
|
@@ -118,7 +120,9 @@
|
|
|
118
120
|
},
|
|
119
121
|
// 当前状态,open-打开,close-关闭
|
|
120
122
|
status: '',
|
|
121
|
-
sliderStyle: {}
|
|
123
|
+
sliderStyle: {},
|
|
124
|
+
// 内部缓存横向滑动状态,避免一次手势重复触发相同事件
|
|
125
|
+
innerScrolling: this.scrolling
|
|
122
126
|
}
|
|
123
127
|
},
|
|
124
128
|
watch: {
|
|
@@ -142,6 +146,14 @@
|
|
|
142
146
|
} else {
|
|
143
147
|
this.status = 'close'
|
|
144
148
|
}
|
|
149
|
+
},
|
|
150
|
+
scrolling(newValue) {
|
|
151
|
+
this.innerScrolling = !!newValue
|
|
152
|
+
},
|
|
153
|
+
disabled(newValue) {
|
|
154
|
+
if (newValue) {
|
|
155
|
+
this.setScrolling(false)
|
|
156
|
+
}
|
|
145
157
|
}
|
|
146
158
|
},
|
|
147
159
|
computed: {
|
|
@@ -160,6 +172,11 @@
|
|
|
160
172
|
},
|
|
161
173
|
beforeUmount() {
|
|
162
174
|
this.closeHandler()
|
|
175
|
+
this.setScrolling(false)
|
|
176
|
+
},
|
|
177
|
+
beforeUnmount() {
|
|
178
|
+
this.closeHandler()
|
|
179
|
+
this.setScrolling(false)
|
|
163
180
|
},
|
|
164
181
|
methods: {
|
|
165
182
|
addUnit,
|
|
@@ -177,6 +194,13 @@
|
|
|
177
194
|
// 此方法在mixin中
|
|
178
195
|
this.getParentData('u-swipe-action')
|
|
179
196
|
},
|
|
197
|
+
setScrolling(value) {
|
|
198
|
+
const next = !!value
|
|
199
|
+
if (this.innerScrolling === next) return
|
|
200
|
+
this.innerScrolling = next
|
|
201
|
+
this.$emit('update:scrolling', next)
|
|
202
|
+
this.$emit('scrolling', next)
|
|
203
|
+
},
|
|
180
204
|
// #ifndef APP-NVUE
|
|
181
205
|
// 查询节点
|
|
182
206
|
queryRect() {
|
|
@@ -11,10 +11,8 @@
|
|
|
11
11
|
class="u-tabbar-item__icon"
|
|
12
12
|
:class="iconClassNames"
|
|
13
13
|
>
|
|
14
|
-
<view v-if="isMidButton" class="u-tabbar-item__mid-button-
|
|
15
|
-
<
|
|
16
|
-
<path d="M 4 36 A 32 32 0 0 1 68 36"></path>
|
|
17
|
-
</svg>
|
|
14
|
+
<view v-if="isMidButton" class="u-tabbar-item__mid-button-border">
|
|
15
|
+
<view class="u-tabbar-item__mid-button-border-circle" :style="midButtonBorderCircleStyle"></view>
|
|
18
16
|
</view>
|
|
19
17
|
<view v-if="isMidButton" class="u-tabbar-item__mid-button-inner"></view>
|
|
20
18
|
<up-icon
|
|
@@ -22,6 +20,7 @@
|
|
|
22
20
|
:name="resolvedIconName"
|
|
23
21
|
:color="isMidButton ? resolvedMidButtonIconColor : (isActive ? resolvedActiveColor : resolvedInactiveColor)"
|
|
24
22
|
:size="isMidButton ? midButtonIconSize : 24"
|
|
23
|
+
:customStyle="midButtonIconStyle"
|
|
25
24
|
></up-icon>
|
|
26
25
|
<template v-else>
|
|
27
26
|
<slot
|
|
@@ -94,7 +93,8 @@
|
|
|
94
93
|
inactiveBackgroundColor: '',
|
|
95
94
|
itemShape: 'default',
|
|
96
95
|
iconScale: 1.1,
|
|
97
|
-
textMode: 'always'
|
|
96
|
+
textMode: 'always',
|
|
97
|
+
borderColor: ''
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
},
|
|
@@ -135,10 +135,41 @@
|
|
|
135
135
|
if (this.midButtonIconColor) return this.midButtonIconColor
|
|
136
136
|
return this.isMidButton ? '#3c9cff' : this.resolvedActiveColor
|
|
137
137
|
},
|
|
138
|
+
midButtonIconStyle() {
|
|
139
|
+
return this.isMidButton
|
|
140
|
+
? {
|
|
141
|
+
position: 'relative',
|
|
142
|
+
zIndex: 2
|
|
143
|
+
}
|
|
144
|
+
: {}
|
|
145
|
+
},
|
|
146
|
+
hasMidButtonText() {
|
|
147
|
+
return !!this.$slots.text || String(this.text || '').length > 0
|
|
148
|
+
},
|
|
149
|
+
resolvedMidButtonOffsetY() {
|
|
150
|
+
const offset = Number.parseFloat(this.midButtonOffsetY)
|
|
151
|
+
return Number.isFinite(offset) ? offset : -10
|
|
152
|
+
},
|
|
153
|
+
midButtonTranslateY() {
|
|
154
|
+
return `${this.resolvedMidButtonOffsetY}px`
|
|
155
|
+
},
|
|
156
|
+
midButtonBorderClipHeight() {
|
|
157
|
+
const clipBaseHeight = this.hasMidButtonText ? 15.5 : 7
|
|
158
|
+
const clipHeight = clipBaseHeight - this.resolvedMidButtonOffsetY
|
|
159
|
+
return `${Math.min(Math.max(clipHeight, 0), 64)}px`
|
|
160
|
+
},
|
|
161
|
+
midButtonBorderCircleStyle() {
|
|
162
|
+
return this.isMidButton && this.parentData.borderColor
|
|
163
|
+
? {
|
|
164
|
+
borderColor: this.parentData.borderColor
|
|
165
|
+
}
|
|
166
|
+
: {}
|
|
167
|
+
},
|
|
138
168
|
itemClassNames() {
|
|
139
169
|
return [
|
|
140
170
|
this.isActive ? 'u-tabbar-item--active' : 'u-tabbar-item--inactive',
|
|
141
171
|
this.isMidButton ? 'u-tabbar-item--mid-button' : '',
|
|
172
|
+
this.isMidButton && !this.hasMidButtonText ? 'u-tabbar-item--mid-button-no-text' : '',
|
|
142
173
|
`u-tabbar-item--${this.resolvedStyleType}`,
|
|
143
174
|
this.resolvedAnimationType !== 'none' && this.isActive ? `u-tabbar-item--anim-${this.resolvedAnimationType}` : '',
|
|
144
175
|
this.resolvedItemShape !== 'default' ? `u-tabbar-item--shape-${this.resolvedItemShape}` : '',
|
|
@@ -276,6 +307,11 @@
|
|
|
276
307
|
|
|
277
308
|
&--mid-button {
|
|
278
309
|
justify-content: center;
|
|
310
|
+
position: relative;
|
|
311
|
+
z-index: 1;
|
|
312
|
+
/* #ifndef APP-NVUE */
|
|
313
|
+
transform: translateY(v-bind('midButtonTranslateY'));
|
|
314
|
+
/* #endif */
|
|
279
315
|
}
|
|
280
316
|
}
|
|
281
317
|
|
|
@@ -381,9 +417,6 @@
|
|
|
381
417
|
|
|
382
418
|
// 中间按钮样式
|
|
383
419
|
.u-tabbar-item--mid-button {
|
|
384
|
-
/* #ifndef APP-NVUE */
|
|
385
|
-
transform: translateY(v-bind('`${midButtonOffsetY}px`'));
|
|
386
|
-
/* #endif */
|
|
387
420
|
z-index: 2;
|
|
388
421
|
flex: 1;
|
|
389
422
|
}
|
|
@@ -401,26 +434,36 @@
|
|
|
401
434
|
overflow: visible;
|
|
402
435
|
}
|
|
403
436
|
|
|
404
|
-
.u-tabbar-item__mid-button-
|
|
437
|
+
.u-tabbar-item__mid-button-border {
|
|
405
438
|
position: absolute;
|
|
406
|
-
left:
|
|
407
|
-
top:
|
|
408
|
-
width:
|
|
409
|
-
height:
|
|
439
|
+
left: 0;
|
|
440
|
+
top: 0;
|
|
441
|
+
width: 64px;
|
|
442
|
+
height: v-bind('midButtonBorderClipHeight');
|
|
443
|
+
box-sizing: border-box;
|
|
444
|
+
background: transparent;
|
|
445
|
+
overflow: hidden;
|
|
410
446
|
pointer-events: none;
|
|
411
447
|
z-index: 0;
|
|
412
448
|
}
|
|
413
449
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
height:
|
|
450
|
+
/* #ifdef APP-NVUE */
|
|
451
|
+
.u-tabbar-item__mid-button-border {
|
|
452
|
+
height: 15.5px;
|
|
417
453
|
}
|
|
418
454
|
|
|
419
|
-
.u-tabbar-item__mid-button-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
455
|
+
.u-tabbar-item--mid-button-no-text .u-tabbar-item__mid-button-border {
|
|
456
|
+
height: 7px;
|
|
457
|
+
}
|
|
458
|
+
/* #endif */
|
|
459
|
+
|
|
460
|
+
.u-tabbar-item__mid-button-border-circle {
|
|
461
|
+
width: 64px;
|
|
462
|
+
height: 64px;
|
|
463
|
+
box-sizing: border-box;
|
|
464
|
+
background: transparent;
|
|
465
|
+
border: 1px solid var(--up-border-color, rgba(0, 0, 0, 0.08));
|
|
466
|
+
border-radius: 999px;
|
|
424
467
|
}
|
|
425
468
|
|
|
426
469
|
.u-tabbar-item__mid-button-inner {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
class="u-tabs__wrapper__scroll-view" :show-scrollbar="false" ref="u-tabs__wrapper__scroll-view">
|
|
8
8
|
<view class="u-tabs__wrapper__nav" ref="u-tabs__wrapper__nav">
|
|
9
9
|
<view class="u-tabs__wrapper__nav__item" v-for="(item, index) in tabList" :key="index"
|
|
10
|
-
@tap="clickHandler(item, index)" @longpress="longPressHandler(item,index)"
|
|
10
|
+
@tap="clickHandler(item, index, $event)" @longpress="longPressHandler(item,index)"
|
|
11
11
|
:ref="`u-tabs__wrapper__nav__item-${index}`"
|
|
12
12
|
:style="[itemComputedStyle, {flex: scrollable ? '' : 1}]" :class="[`u-tabs__wrapper__nav__item-${index}`,
|
|
13
13
|
shapeMode && `u-tabs__wrapper__nav__item--${shapeMode}`,
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
* @property {String} keyName 从`list`元素对象中读取的键名(默认 'name' )
|
|
109
109
|
* @property {String} shapeMode 标签形态模式,可选capsule/card/pill-arrow/tag(默认 '' )
|
|
110
110
|
* @event {Function(index)} change 标签改变时触发 index: 点击了第几个tab,索引从0开始
|
|
111
|
-
* @event {Function(index)} click
|
|
111
|
+
* @event {Function(item, index, event)} click 点击标签时触发,event 为原始点击事件
|
|
112
112
|
* @event {Function(index)} longPress 长按标签时触发 index: 点击了第几个tab,索引从0开始
|
|
113
113
|
* @example <u-tabs :list="list" :is-scroll="false" :current="current" @change="change" @longPress="longPress"></u-tabs>
|
|
114
114
|
*/
|
|
@@ -195,10 +195,13 @@
|
|
|
195
195
|
const isActive = index == this.innerCurrent
|
|
196
196
|
const defaultActiveColor = defProps.tabs?.activeStyle?.color || '#303133'
|
|
197
197
|
const defaultInactiveColor = defProps.tabs?.inactiveStyle?.color || '#606266'
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
198
|
+
const hasCustomColor = customeStyle
|
|
199
|
+
&& Object.prototype.hasOwnProperty.call(customeStyle, 'color')
|
|
200
|
+
&& String(customeStyle.color ?? '').trim() !== ''
|
|
201
|
+
const isActiveStyleOverridden = hasCustomColor && (this.upHasProp('activeStyle')
|
|
202
|
+
|| customeStyle.color !== defaultActiveColor)
|
|
203
|
+
const isInactiveStyleOverridden = hasCustomColor && (this.upHasProp('inactiveStyle')
|
|
204
|
+
|| customeStyle.color !== defaultInactiveColor)
|
|
202
205
|
if (isActive && ['pill-arrow', 'tag'].includes(this.shapeMode) && !isActiveStyleOverridden) {
|
|
203
206
|
style.color = '#ffffff'
|
|
204
207
|
} else if (isActive && !isActiveStyleOverridden) {
|
|
@@ -267,12 +270,12 @@
|
|
|
267
270
|
// #endif
|
|
268
271
|
},
|
|
269
272
|
// 点击某一个标签
|
|
270
|
-
clickHandler(item, index) {
|
|
273
|
+
clickHandler(item, index, event) {
|
|
271
274
|
// 因为标签可能为disabled状态,所以click是一定会发出的,但是change事件是需要可用的状态才发出
|
|
272
275
|
this.$emit('click', {
|
|
273
276
|
...item,
|
|
274
277
|
index
|
|
275
|
-
}, index)
|
|
278
|
+
}, index, event)
|
|
276
279
|
// 如果disabled状态,返回
|
|
277
280
|
if (item.disabled) return
|
|
278
281
|
// 如果点击当前不触发change
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="u-tabs-pro" :class="customClass" :style="customStyle">
|
|
3
|
+
<up-tabs
|
|
4
|
+
:list="safeList"
|
|
5
|
+
:keyName="keyName"
|
|
6
|
+
:current="innerCurrent"
|
|
7
|
+
:lineColor="resolvedLineColor"
|
|
8
|
+
:activeStyle="activeStyle"
|
|
9
|
+
:inactiveStyle="inactiveStyle"
|
|
10
|
+
:lineWidth="lineWidth"
|
|
11
|
+
:lineHeight="lineHeight"
|
|
12
|
+
:lineBgSize="lineBgSize"
|
|
13
|
+
:itemStyle="itemStyle"
|
|
14
|
+
:scrollable="scrollable"
|
|
15
|
+
:duration="Number(duration)"
|
|
16
|
+
:iconStyle="iconStyle"
|
|
17
|
+
:shapeMode="shapeMode"
|
|
18
|
+
@update:current="updateCurrent"
|
|
19
|
+
@click="clickHandler"
|
|
20
|
+
@longPress="longPressHandler"
|
|
21
|
+
@change="changeHandler"
|
|
22
|
+
>
|
|
23
|
+
<template v-if="$slots.left" #left>
|
|
24
|
+
<slot name="left" />
|
|
25
|
+
</template>
|
|
26
|
+
<template v-if="$slots.icon" #icon="scope">
|
|
27
|
+
<slot name="icon" :item="scope.item" :keyName="scope.keyName" :index="scope.index" />
|
|
28
|
+
</template>
|
|
29
|
+
<template v-if="$slots.tab || $slots.content" #content="scope">
|
|
30
|
+
<slot name="tab" :item="scope.item" :keyName="scope.keyName" :index="scope.index">
|
|
31
|
+
<slot name="content" :item="scope.item" :keyName="scope.keyName" :index="scope.index" />
|
|
32
|
+
</slot>
|
|
33
|
+
</template>
|
|
34
|
+
<template v-if="$slots.right" #right>
|
|
35
|
+
<slot name="right" />
|
|
36
|
+
</template>
|
|
37
|
+
</up-tabs>
|
|
38
|
+
<view
|
|
39
|
+
v-if="showContent"
|
|
40
|
+
class="u-tabs-pro__content"
|
|
41
|
+
:class="contentClass"
|
|
42
|
+
:style="contentStyle"
|
|
43
|
+
>
|
|
44
|
+
<slot
|
|
45
|
+
:current="innerCurrent"
|
|
46
|
+
:index="innerCurrent"
|
|
47
|
+
:item="currentItem"
|
|
48
|
+
:value="currentValue"
|
|
49
|
+
:list="safeList"
|
|
50
|
+
/>
|
|
51
|
+
</view>
|
|
52
|
+
</view>
|
|
53
|
+
</template>
|
|
54
|
+
|
|
55
|
+
<script>
|
|
56
|
+
import { mpMixin } from '../../libs/mixin/mpMixin'
|
|
57
|
+
import { mixin } from '../../libs/mixin/mixin'
|
|
58
|
+
|
|
59
|
+
export default {
|
|
60
|
+
name: 'u-tabs-pro',
|
|
61
|
+
mixins: [mpMixin, mixin],
|
|
62
|
+
props: {
|
|
63
|
+
list: {
|
|
64
|
+
type: Array,
|
|
65
|
+
default: () => []
|
|
66
|
+
},
|
|
67
|
+
keyName: {
|
|
68
|
+
type: String,
|
|
69
|
+
default: 'name'
|
|
70
|
+
},
|
|
71
|
+
current: {
|
|
72
|
+
type: [Number, String],
|
|
73
|
+
default: 0
|
|
74
|
+
},
|
|
75
|
+
contentMode: {
|
|
76
|
+
type: String,
|
|
77
|
+
default: 'static'
|
|
78
|
+
},
|
|
79
|
+
lineColor: {
|
|
80
|
+
type: String,
|
|
81
|
+
default: ''
|
|
82
|
+
},
|
|
83
|
+
activeStyle: {
|
|
84
|
+
type: [String, Object],
|
|
85
|
+
default: () => ({})
|
|
86
|
+
},
|
|
87
|
+
inactiveStyle: {
|
|
88
|
+
type: [String, Object],
|
|
89
|
+
default: () => ({})
|
|
90
|
+
},
|
|
91
|
+
lineWidth: {
|
|
92
|
+
type: [String, Number],
|
|
93
|
+
default: 20
|
|
94
|
+
},
|
|
95
|
+
lineHeight: {
|
|
96
|
+
type: [String, Number],
|
|
97
|
+
default: 3
|
|
98
|
+
},
|
|
99
|
+
lineBgSize: {
|
|
100
|
+
type: String,
|
|
101
|
+
default: 'cover'
|
|
102
|
+
},
|
|
103
|
+
itemStyle: {
|
|
104
|
+
type: [String, Object],
|
|
105
|
+
default: () => ({ height: '44px' })
|
|
106
|
+
},
|
|
107
|
+
scrollable: {
|
|
108
|
+
type: Boolean,
|
|
109
|
+
default: true
|
|
110
|
+
},
|
|
111
|
+
duration: {
|
|
112
|
+
type: [Number, String],
|
|
113
|
+
default: 300
|
|
114
|
+
},
|
|
115
|
+
iconStyle: {
|
|
116
|
+
type: [String, Object],
|
|
117
|
+
default: () => ({})
|
|
118
|
+
},
|
|
119
|
+
shapeMode: {
|
|
120
|
+
type: String,
|
|
121
|
+
default: ''
|
|
122
|
+
},
|
|
123
|
+
showContent: {
|
|
124
|
+
type: Boolean,
|
|
125
|
+
default: true
|
|
126
|
+
},
|
|
127
|
+
contentClass: {
|
|
128
|
+
type: String,
|
|
129
|
+
default: ''
|
|
130
|
+
},
|
|
131
|
+
contentStyle: {
|
|
132
|
+
type: [String, Object, Array],
|
|
133
|
+
default: ''
|
|
134
|
+
},
|
|
135
|
+
bindIndexRef: {
|
|
136
|
+
type: String,
|
|
137
|
+
default: ''
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
emits: ['click', 'longPress', 'change', 'update:current'],
|
|
141
|
+
data() {
|
|
142
|
+
return {
|
|
143
|
+
innerCurrent: 0
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
computed: {
|
|
147
|
+
safeList() {
|
|
148
|
+
return Array.isArray(this.list) ? this.list : []
|
|
149
|
+
},
|
|
150
|
+
currentItem() {
|
|
151
|
+
return this.safeList[this.innerCurrent] || null
|
|
152
|
+
},
|
|
153
|
+
currentValue() {
|
|
154
|
+
return this.currentItem ? this.currentItem[this.keyName] : undefined
|
|
155
|
+
},
|
|
156
|
+
resolvedLineColor() {
|
|
157
|
+
return this.lineColor || undefined
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
watch: {
|
|
161
|
+
current: {
|
|
162
|
+
immediate: true,
|
|
163
|
+
handler(value) {
|
|
164
|
+
this.innerCurrent = this.normalizeCurrent(value)
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
list: {
|
|
168
|
+
deep: true,
|
|
169
|
+
handler() {
|
|
170
|
+
const nextCurrent = this.normalizeCurrent(this.innerCurrent)
|
|
171
|
+
if (nextCurrent !== this.innerCurrent) {
|
|
172
|
+
this.innerCurrent = nextCurrent
|
|
173
|
+
this.$emit('update:current', nextCurrent)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
methods: {
|
|
179
|
+
normalizeCurrent(value) {
|
|
180
|
+
const parsed = Number(value)
|
|
181
|
+
const nextValue = Number.isFinite(parsed) ? parsed : 0
|
|
182
|
+
const maxIndex = Math.max(this.safeList.length - 1, 0)
|
|
183
|
+
return Math.min(Math.max(nextValue, 0), maxIndex)
|
|
184
|
+
},
|
|
185
|
+
updateCurrent(value) {
|
|
186
|
+
const nextCurrent = this.normalizeCurrent(value)
|
|
187
|
+
this.innerCurrent = nextCurrent
|
|
188
|
+
this.$emit('update:current', nextCurrent)
|
|
189
|
+
},
|
|
190
|
+
clickHandler(item, index, event) {
|
|
191
|
+
this.$emit('click', item, index, event)
|
|
192
|
+
},
|
|
193
|
+
longPressHandler(item, index) {
|
|
194
|
+
this.$emit('longPress', item, index)
|
|
195
|
+
},
|
|
196
|
+
changeHandler(item, index) {
|
|
197
|
+
this.updateCurrent(index)
|
|
198
|
+
this.$emit('change', item, index)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
</script>
|
|
203
|
+
|
|
204
|
+
<style lang="scss" scoped>
|
|
205
|
+
.u-tabs-pro {
|
|
206
|
+
width: 100%;
|
|
207
|
+
|
|
208
|
+
&__content {
|
|
209
|
+
width: 100%;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
</style>
|
|
@@ -73,10 +73,22 @@ import value from './value.js'
|
|
|
73
73
|
import { mpMixin } from '../../libs/mixin/mpMixin';
|
|
74
74
|
import { mixin } from '../../libs/mixin/mixin';
|
|
75
75
|
import { buttonMixin } from '../../libs/mixin/button';
|
|
76
|
-
import { openType } from '../../libs/mixin/openType';
|
|
77
|
-
import { addStyle, addUnit, deepMerge } from '../../libs/function/index';
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
import { openType } from '../../libs/mixin/openType';
|
|
77
|
+
import { addStyle, addUnit, deepMerge } from '../../libs/function/index';
|
|
78
|
+
|
|
79
|
+
function normalizeLineHeight(value) {
|
|
80
|
+
const valueString = String(value).trim()
|
|
81
|
+
const numericValue = Number(valueString)
|
|
82
|
+
const isUnitless =
|
|
83
|
+
/^[+-]?(?:\d+\.?\d*|\.\d+)$/.test(valueString) &&
|
|
84
|
+
numericValue > 0 &&
|
|
85
|
+
numericValue < 10
|
|
86
|
+
|
|
87
|
+
return isUnitless ? valueString : addUnit(value)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Text 文本
|
|
80
92
|
* @description 此组件集成了文本类在项目中的常用功能,包括状态,拨打电话,格式化日期,*替换,超链接...等功能。 您大可不必在使用特殊文本时自己定义,text组件几乎涵盖您能使用的大部分场景。
|
|
81
93
|
* @tutorial https://uview-plus.jiangruyi.com/components/loading.html
|
|
82
94
|
* @property {String} type 主题颜色
|
|
@@ -97,7 +109,7 @@ import { addStyle, addUnit, deepMerge } from '../../libs/function/index';
|
|
|
97
109
|
* @property {Object | String} iconStyle 图标的样式 (默认 {fontSize: '15px'} )
|
|
98
110
|
* @property {String} decoration 文字装饰,下划线,中划线等,可选值 none|underline|line-through(默认 'none' )
|
|
99
111
|
* @property {Object | String | Number} margin 外边距,对象、字符串,数值形式均可(默认 0 )
|
|
100
|
-
* @property {String | Number} lineHeight
|
|
112
|
+
* @property {String | Number} lineHeight 文本行高,支持带单位值或无单位倍数(如 1.2)
|
|
101
113
|
* @property {String} align 文本对齐方式,可选值left|center|right(默认 'left' )
|
|
102
114
|
* @property {String} wordWrap 文字换行,可选值break-word|normal|anywhere(默认 'normal' )
|
|
103
115
|
* @event {Function} click 点击触发事件
|
|
@@ -139,7 +151,7 @@ export default {
|
|
|
139
151
|
}
|
|
140
152
|
this.isNvue && this.lines && (style.lines = this.lines)
|
|
141
153
|
this.lineHeight &&
|
|
142
|
-
(style.lineHeight =
|
|
154
|
+
(style.lineHeight = normalizeLineHeight(this.lineHeight))
|
|
143
155
|
!this.isNvue && this.block && (style.display = 'block')
|
|
144
156
|
return deepMerge(style, addStyle(this.customStyle))
|
|
145
157
|
},
|
|
@@ -875,7 +875,7 @@
|
|
|
875
875
|
bottom: $u-upload-success-bottom;
|
|
876
876
|
right: $u-upload-success-right;
|
|
877
877
|
@include flex;
|
|
878
|
-
// 由于weex(nvue)
|
|
878
|
+
// 由于weex(nvue)不支持css绘制三角形
|
|
879
879
|
// 所以在nvue下使用图片,非nvue下使用css实现
|
|
880
880
|
/* #ifndef APP-NVUE */
|
|
881
881
|
border-style: $u-upload-success-border-style;
|