oxy-uni-ui 2.1.2 → 2.1.3
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/attributes.json +1 -1
- package/components/common/AbortablePromise.ts +4 -0
- package/components/common/abstracts/variable.scss +172 -66
- package/components/common/base64.ts +6 -0
- package/components/common/clickoutside.ts +5 -0
- package/components/common/interceptor.ts +9 -0
- package/components/common/path.ts +4 -0
- package/components/common/props.ts +23 -0
- package/components/common/util.ts +18 -1
- package/components/composables/index.ts +2 -0
- package/components/composables/useCell.ts +8 -1
- package/components/composables/useChildren.ts +27 -1
- package/components/composables/useCountDown.ts +10 -1
- package/components/composables/useDynamicVirtualScroll.ts +9 -0
- package/components/composables/useGlobalLoading.ts +6 -0
- package/components/composables/useGlobalMessage.ts +6 -0
- package/components/composables/useGlobalToast.ts +6 -0
- package/components/composables/useLockScroll.ts +9 -0
- package/components/composables/useParent.ts +65 -14
- package/components/composables/usePopover.ts +9 -0
- package/components/composables/useQueue.ts +8 -0
- package/components/composables/useRaf.ts +10 -0
- package/components/composables/useSharedState.ts +284 -0
- package/components/composables/useTouch.ts +8 -0
- package/components/composables/useTranslate.ts +9 -0
- package/components/composables/useUpload.ts +83 -11
- package/components/composables/useVirtualScroll.ts +7 -0
- package/components/composables/useWindowResize.ts +9 -0
- package/components/oxy-action-sheet/index.scss +5 -5
- package/components/oxy-action-sheet/oxy-action-sheet.vue +11 -0
- package/components/oxy-backtop/index.scss +2 -2
- package/components/oxy-backtop/oxy-backtop.vue +2 -0
- package/components/oxy-badge/oxy-badge.vue +2 -0
- package/components/oxy-badge/types.ts +3 -0
- package/components/oxy-button/index.scss +13 -13
- package/components/oxy-button/oxy-button.vue +11 -0
- package/components/oxy-button/types.ts +3 -3
- package/components/oxy-calendar/index.scss +17 -17
- package/components/oxy-calendar/oxy-calendar.vue +31 -0
- package/components/oxy-calendar/types.ts +3 -0
- package/components/oxy-calendar-view/month/month.vue +2 -0
- package/components/oxy-calendar-view/monthPanel/month-panel.vue +3 -1
- package/components/oxy-calendar-view/monthPanel/types.ts +10 -7
- package/components/oxy-calendar-view/oxy-calendar-view.vue +2 -0
- package/components/oxy-calendar-view/types.ts +3 -1
- package/components/oxy-calendar-view/year/types.ts +33 -1
- package/components/oxy-calendar-view/year/year.vue +2 -0
- package/components/oxy-calendar-view/yearPanel/year-panel.vue +2 -0
- package/components/oxy-card/index.scss +1 -1
- package/components/oxy-card/oxy-card.vue +2 -0
- package/components/oxy-cell/index.scss +3 -1
- package/components/oxy-cell/oxy-cell.vue +6 -4
- package/components/oxy-cell-group/oxy-cell-group.vue +2 -0
- package/components/oxy-checkbox/index.scss +7 -7
- package/components/oxy-checkbox/oxy-checkbox.vue +22 -16
- package/components/oxy-checkbox/types.ts +9 -0
- package/components/oxy-checkbox-group/index.scss +1 -1
- package/components/oxy-checkbox-group/oxy-checkbox-group.vue +2 -0
- package/components/oxy-circle/oxy-circle.vue +2 -0
- package/components/oxy-col/oxy-col.vue +3 -1
- package/components/oxy-col-picker/index.scss +3 -3
- package/components/oxy-col-picker/oxy-col-picker.vue +17 -1
- package/components/oxy-col-picker/types.ts +3 -0
- package/components/oxy-collapse/index.scss +2 -2
- package/components/oxy-collapse/oxy-collapse.vue +9 -0
- package/components/oxy-collapse-item/oxy-collapse-item.vue +4 -2
- package/components/oxy-config-provider/oxy-config-provider.vue +18 -0
- package/components/oxy-config-provider/types.ts +18 -0
- package/components/oxy-corner/index.scss +50 -32
- package/components/oxy-corner/oxy-corner.vue +2 -0
- package/components/oxy-count-down/oxy-count-down.vue +2 -0
- package/components/oxy-count-to/oxy-count-to.vue +12 -1
- package/components/oxy-count-to/types.ts +14 -4
- package/components/oxy-curtain/index.scss +10 -9
- package/components/oxy-curtain/oxy-curtain.vue +2 -0
- package/components/oxy-date-strip/oxy-date-strip.vue +22 -1
- package/components/oxy-date-strip-item/index.scss +4 -4
- package/components/oxy-date-strip-item/oxy-date-strip-item.vue +2 -0
- package/components/oxy-datetime-picker/index.scss +3 -3
- package/components/oxy-datetime-picker/oxy-datetime-picker.vue +11 -1
- package/components/oxy-datetime-picker-view/oxy-datetime-picker-view.vue +2 -0
- package/components/oxy-divider/oxy-divider.vue +2 -0
- package/components/oxy-drop-menu/index.scss +2 -2
- package/components/oxy-drop-menu/oxy-drop-menu.vue +3 -0
- package/components/oxy-drop-menu-item/index.scss +1 -1
- package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +17 -9
- package/components/oxy-echarts/oxy-echarts.vue +2 -0
- package/components/oxy-fab/index.scss +1 -1
- package/components/oxy-fab/oxy-fab.vue +27 -0
- package/components/oxy-file-list/index.scss +9 -9
- package/components/oxy-file-list/oxy-file-list.vue +29 -17
- package/components/oxy-floating-panel/oxy-floating-panel.vue +34 -10
- package/components/oxy-footer/index.scss +7 -0
- package/components/oxy-footer/oxy-footer.vue +4 -2
- package/components/oxy-footer/types.ts +9 -6
- package/components/oxy-form/oxy-form.vue +13 -1
- package/components/oxy-form-item/oxy-form-item.vue +5 -3
- package/components/oxy-gap/oxy-gap.vue +2 -0
- package/components/oxy-global-loading/oxy-global-loading.vue +18 -5
- package/components/oxy-global-message/oxy-global-message.vue +30 -17
- package/components/oxy-global-toast/oxy-global-toast.vue +18 -5
- package/components/oxy-grid/oxy-grid.vue +6 -0
- package/components/oxy-grid-item/index.scss +1 -1
- package/components/oxy-grid-item/oxy-grid-item.vue +22 -20
- package/components/oxy-guidance/index.scss +9 -9
- package/components/oxy-guidance/oxy-guidance.vue +22 -16
- package/components/oxy-icon/oxy-icon.vue +2 -0
- package/components/oxy-icon/types.ts +3 -0
- package/components/oxy-image-preview/index.scss +75 -0
- package/components/oxy-image-preview/index.ts +56 -0
- package/components/oxy-image-preview/oxy-image-preview.vue +221 -0
- package/components/oxy-image-preview/types.ts +164 -0
- package/components/oxy-img/oxy-img.vue +2 -0
- package/components/oxy-img-cropper/index.scss +2 -2
- package/components/oxy-img-cropper/oxy-img-cropper.vue +6 -0
- package/components/oxy-img-lazy/oxy-img-lazy.vue +9 -0
- package/components/oxy-index-anchor/index.scss +1 -1
- package/components/oxy-index-anchor/oxy-index-anchor.vue +2 -2
- package/components/oxy-index-bar/index.scss +1 -1
- package/components/oxy-index-bar/oxy-index-bar.vue +18 -0
- package/components/oxy-input/index.scss +2 -1
- package/components/oxy-input/oxy-input.vue +18 -4
- package/components/oxy-input/types.ts +6 -0
- package/components/oxy-input-number/index.scss +3 -1
- package/components/oxy-input-number/oxy-input-number.vue +2 -0
- package/components/oxy-keyboard/index.scss +3 -3
- package/components/oxy-keyboard/key/index.vue +2 -0
- package/components/oxy-keyboard/oxy-keyboard.vue +11 -2
- package/components/oxy-link/index.scss +8 -4
- package/components/oxy-link/oxy-link.vue +9 -3
- package/components/oxy-link/types.ts +2 -2
- package/components/oxy-list/oxy-list.vue +2 -0
- package/components/oxy-list/types.ts +7 -0
- package/components/oxy-loading/oxy-loading.vue +6 -0
- package/components/oxy-loadmore/index.scss +1 -1
- package/components/oxy-loadmore/oxy-loadmore.vue +2 -0
- package/components/oxy-long-press-menu/index.scss +1 -1
- package/components/oxy-long-press-menu/oxy-long-press-menu.vue +42 -13
- package/components/oxy-message-box/index.scss +223 -36
- package/components/oxy-message-box/index.ts +49 -23
- package/components/oxy-message-box/oxy-message-box.vue +181 -56
- package/components/oxy-message-box/types.ts +60 -2
- package/components/oxy-navbar/index.scss +1 -1
- package/components/oxy-navbar/oxy-navbar.vue +9 -6
- package/components/oxy-navbar-capsule/oxy-navbar-capsule.vue +2 -0
- package/components/oxy-notice-bar/index.scss +1 -1
- package/components/oxy-notice-bar/oxy-notice-bar.vue +29 -0
- package/components/oxy-notify/index.ts +16 -12
- package/components/oxy-notify/oxy-notify.vue +11 -4
- package/components/oxy-overlay/oxy-overlay.vue +34 -2
- package/components/oxy-pagination/oxy-pagination.vue +2 -0
- package/components/oxy-password-input/oxy-password-input.vue +2 -0
- package/components/oxy-picker/index.scss +7 -7
- package/components/oxy-picker/oxy-picker.vue +11 -0
- package/components/oxy-picker-view/index.scss +1 -1
- package/components/oxy-picker-view/oxy-picker-view.vue +2 -0
- package/components/oxy-popover/index.scss +2 -2
- package/components/oxy-popover/oxy-popover.vue +4 -1
- package/components/oxy-popup/oxy-popup.vue +8 -0
- package/components/oxy-progress/index.scss +2 -2
- package/components/oxy-progress/oxy-progress.vue +7 -0
- package/components/oxy-qrcode/draw.ts +15 -1
- package/components/oxy-qrcode/oxy-qrcode.vue +10 -3
- package/components/oxy-radio/index.scss +8 -8
- package/components/oxy-radio/oxy-radio.vue +13 -11
- package/components/oxy-radio-group/index.scss +1 -1
- package/components/oxy-radio-group/oxy-radio-group.vue +2 -0
- package/components/oxy-rate/oxy-rate.vue +5 -0
- package/components/oxy-rate/types.ts +2 -2
- package/components/oxy-resize/oxy-resize.vue +12 -0
- package/components/oxy-rich-text/index.scss +9 -9
- package/components/oxy-rich-text/oxy-rich-text.vue +6 -0
- package/components/oxy-rich-text/types.ts +15 -0
- package/components/oxy-root-portal/oxy-root-portal.vue +23 -15
- package/components/oxy-row/oxy-row.vue +2 -0
- package/components/oxy-search/index.scss +3 -3
- package/components/oxy-search/oxy-search.vue +19 -0
- package/components/oxy-segmented/index.scss +4 -4
- package/components/oxy-segmented/oxy-segmented.vue +2 -0
- package/components/oxy-select/index.scss +25 -25
- package/components/oxy-select/oxy-select.vue +27 -0
- package/components/oxy-select/types.ts +3 -0
- package/components/oxy-select-picker/index.scss +5 -5
- package/components/oxy-select-picker/oxy-select-picker.vue +7 -0
- package/components/oxy-sidebar/oxy-sidebar.vue +2 -0
- package/components/oxy-sidebar-item/index.scss +3 -3
- package/components/oxy-sidebar-item/oxy-sidebar-item.vue +17 -31
- package/components/oxy-signature/oxy-signature.vue +17 -0
- package/components/oxy-skeleton/oxy-skeleton.vue +7 -1
- package/components/oxy-slide-verify/index.scss +95 -0
- package/components/oxy-slide-verify/oxy-slide-verify.vue +244 -0
- package/components/oxy-slide-verify/types.ts +98 -0
- package/components/oxy-slider/oxy-slider.vue +3 -0
- package/components/oxy-sort-button/index.scss +10 -8
- package/components/oxy-sort-button/oxy-sort-button.vue +6 -0
- package/components/oxy-splitter/index.scss +9 -0
- package/components/oxy-splitter/oxy-splitter.vue +23 -2
- package/components/oxy-splitter-panel/index.scss +7 -5
- package/components/oxy-splitter-panel/oxy-splitter-panel.vue +93 -89
- package/components/oxy-status-tip/index.scss +3 -3
- package/components/oxy-status-tip/oxy-status-tip.vue +2 -0
- package/components/oxy-step/index.scss +4 -4
- package/components/oxy-step/oxy-step.vue +15 -13
- package/components/oxy-steps/oxy-steps.vue +2 -0
- package/components/oxy-sticky/oxy-sticky.vue +5 -3
- package/components/oxy-stream-render/oxy-stream-render.vue +29 -0
- package/components/oxy-swipe-action/oxy-swipe-action.vue +8 -0
- package/components/oxy-swiper/oxy-swiper.vue +6 -0
- package/components/oxy-swiper-nav/index.scss +4 -4
- package/components/oxy-switch/index.scss +6 -3
- package/components/oxy-switch/oxy-switch.vue +10 -0
- package/components/oxy-tab/index.scss +1 -7
- package/components/oxy-tab/oxy-tab.vue +12 -10
- package/components/oxy-tabbar/oxy-tabbar.vue +5 -0
- package/components/oxy-tabbar-item/oxy-tabbar-item.vue +11 -9
- package/components/oxy-table/index.scss +1 -1
- package/components/oxy-table/oxy-table.vue +8 -0
- package/components/oxy-table/types.ts +3 -0
- package/components/oxy-table-col/oxy-table-col.vue +21 -19
- package/components/oxy-tabs/index.scss +11 -11
- package/components/oxy-tabs/oxy-tabs.vue +17 -0
- package/components/oxy-tag/index.scss +24 -5
- package/components/oxy-tag/oxy-tag.vue +17 -2
- package/components/oxy-tag/types.ts +7 -0
- package/components/oxy-text/oxy-text.vue +12 -1
- package/components/oxy-textarea/index.scss +3 -2
- package/components/oxy-textarea/oxy-textarea.vue +10 -4
- package/components/oxy-toast/index.ts +21 -20
- package/components/oxy-toast/oxy-toast.vue +30 -5
- package/components/oxy-toast/types.ts +20 -9
- package/components/oxy-tooltip/index.scss +1 -1
- package/components/oxy-tooltip/oxy-tooltip.vue +2 -0
- package/components/oxy-transition/index.scss +3 -1
- package/components/oxy-transition/oxy-transition.vue +14 -0
- package/components/oxy-tree/index.scss +3 -3
- package/components/oxy-tree/oxy-tree.vue +28 -5
- package/components/oxy-tree/types.ts +57 -1
- package/components/oxy-upload/index.scss +9 -9
- package/components/oxy-upload/oxy-upload.vue +5 -3
- package/components/oxy-verification-code/oxy-verification-code.vue +24 -0
- package/components/oxy-video-preview/index.scss +12 -7
- package/components/oxy-video-preview/index.ts +64 -0
- package/components/oxy-video-preview/oxy-video-preview.vue +102 -31
- package/components/oxy-video-preview/types.ts +54 -8
- package/components/oxy-virtual-scroll/index.scss +1 -1
- package/components/oxy-virtual-scroll/oxy-virtual-scroll.vue +2 -0
- package/components/oxy-voice-player/index.scss +64 -64
- package/components/oxy-voice-player/oxy-voice-player.vue +38 -10
- package/components/oxy-waterfall/oxy-waterfall.vue +13 -0
- package/components/oxy-waterfall/types.ts +7 -0
- package/components/oxy-waterfall-item/oxy-waterfall-item.vue +9 -0
- package/components/oxy-watermark/oxy-watermark.vue +2 -0
- package/global.d.ts +2 -0
- package/index.ts +2 -0
- package/locale/lang/en-US.ts +51 -2
- package/locale/lang/zh-CN.ts +51 -2
- package/package.json +2 -2
- package/styles/all.scss +125 -0
- package/tags.json +1 -1
- package/vite-plugins/vite-plugin-host-class.ts +166 -0
- package/web-types.json +1 -1
|
@@ -15,7 +15,9 @@ export default {
|
|
|
15
15
|
},
|
|
16
16
|
options: {
|
|
17
17
|
addGlobalClass: true,
|
|
18
|
+
// #ifndef MP-TOUTIAO
|
|
18
19
|
virtualHost: true,
|
|
20
|
+
// #endif
|
|
19
21
|
styleIsolation: 'shared'
|
|
20
22
|
},
|
|
21
23
|
data() {
|
|
@@ -47,6 +49,11 @@ export default {
|
|
|
47
49
|
})
|
|
48
50
|
.join('\n')
|
|
49
51
|
},
|
|
52
|
+
/**
|
|
53
|
+
* 从输入流中提取完整的 JSON 对象。使用深度计数器和字符串状态机,
|
|
54
|
+
* 支持字符串内转义和嵌套 JSON,处理流式传输中 JSON 对象可能跨 chunk 的情况。
|
|
55
|
+
* @returns {{ texts: string[], rest: string }} texts 为完整 JSON 字符串数组,rest 为未完成的部分
|
|
56
|
+
*/
|
|
50
57
|
extractJsonObjects(input) {
|
|
51
58
|
const texts = []
|
|
52
59
|
let start = -1
|
|
@@ -90,6 +97,10 @@ export default {
|
|
|
90
97
|
const rest = start !== -1 ? input.slice(start) : ''
|
|
91
98
|
return { texts, rest }
|
|
92
99
|
},
|
|
100
|
+
/**
|
|
101
|
+
* 解析流数据并向外 emit。累积 pendingText,strip SSE 前缀,提取完整 JSON 对象逐个 emit。
|
|
102
|
+
* finished 为 true 时,清空缓冲区并 emit finished 事件。
|
|
103
|
+
*/
|
|
93
104
|
emitParsedStreamData({ chunk, finished }) {
|
|
94
105
|
if (finished) {
|
|
95
106
|
if (this.pendingText) {
|
|
@@ -121,6 +132,10 @@ export default {
|
|
|
121
132
|
merged.set(b, a.length)
|
|
122
133
|
return merged
|
|
123
134
|
},
|
|
135
|
+
/**
|
|
136
|
+
* 分割可能不完整的 UTF-8 字节序列。从末尾向前扫描 continuation bytes,
|
|
137
|
+
* 通过首字节判断期望的字节数,期望数 > 实际数时截断为 pending 供下次拼接。
|
|
138
|
+
*/
|
|
124
139
|
splitIncompleteUtf8(bytes) {
|
|
125
140
|
const len = bytes.length
|
|
126
141
|
if (len === 0) {
|
|
@@ -157,6 +172,10 @@ export default {
|
|
|
157
172
|
|
|
158
173
|
return { complete: bytes, pending: null }
|
|
159
174
|
},
|
|
175
|
+
/**
|
|
176
|
+
* 手写 UTF-8 解码器(用于小程序等不支持 TextDecoder 的环境)。
|
|
177
|
+
* 支持 1-4 字节编码,包括 BMP 内字符和代理对(surrogate pair)。
|
|
178
|
+
*/
|
|
160
179
|
utf8Decode(bytes) {
|
|
161
180
|
let out = ''
|
|
162
181
|
for (let i = 0; i < bytes.length; i++) {
|
|
@@ -219,6 +238,10 @@ export default {
|
|
|
219
238
|
}
|
|
220
239
|
return out
|
|
221
240
|
},
|
|
241
|
+
/**
|
|
242
|
+
* 小程序端 chunk 解码。将 Uint8Array chunk 合并到 pending buffer,
|
|
243
|
+
* 分割 UTF-8 边界后解码文本。finished 时清空 pending。
|
|
244
|
+
*/
|
|
222
245
|
decodeMpChunk(data, finished) {
|
|
223
246
|
if (finished) {
|
|
224
247
|
let tail = null
|
|
@@ -258,6 +281,12 @@ export default {
|
|
|
258
281
|
this.$emit('stream-error', { message, type })
|
|
259
282
|
},
|
|
260
283
|
// #ifndef H5 || APP-PLUS
|
|
284
|
+
/**
|
|
285
|
+
* 小程序端流式请求处理。
|
|
286
|
+
* - cancel 模式:abort 请求并 finished
|
|
287
|
+
* - 正常请求:创建 uni.request(enableChunked),通过 onChunkReceived 逐块解码,
|
|
288
|
+
* success/fail 后清理缓冲区并 finish/error
|
|
289
|
+
*/
|
|
261
290
|
handleStreamRequest(newVal) {
|
|
262
291
|
if (newVal && newVal.cancel) {
|
|
263
292
|
if (this.requestTask) {
|
|
@@ -29,7 +29,9 @@ export default {
|
|
|
29
29
|
name: 'oxy-swipe-action',
|
|
30
30
|
options: {
|
|
31
31
|
addGlobalClass: true,
|
|
32
|
+
// #ifndef MP-TOUTIAO
|
|
32
33
|
virtualHost: true,
|
|
34
|
+
// #endif
|
|
33
35
|
styleIsolation: 'shared'
|
|
34
36
|
}
|
|
35
37
|
}
|
|
@@ -102,6 +104,12 @@ onBeforeUnmount(() => {
|
|
|
102
104
|
}
|
|
103
105
|
})
|
|
104
106
|
|
|
107
|
+
/**
|
|
108
|
+
* 根据 modelValue 控制滑动状态
|
|
109
|
+
* 获取按钮宽度后,switch 到对应状态(close/left/right)
|
|
110
|
+
* @param value - 目标状态
|
|
111
|
+
* @param old - 旧状态(用于关闭时避免重复动画)
|
|
112
|
+
*/
|
|
105
113
|
function changeState(value: SwipeActionStatus, old?: SwipeActionStatus) {
|
|
106
114
|
if (props.disabled) {
|
|
107
115
|
return
|
|
@@ -80,7 +80,9 @@ export default {
|
|
|
80
80
|
name: 'oxy-swiper',
|
|
81
81
|
options: {
|
|
82
82
|
addGlobalClass: true,
|
|
83
|
+
// #ifndef MP-TOUTIAO
|
|
83
84
|
virtualHost: true,
|
|
85
|
+
// #endif
|
|
84
86
|
styleIsolation: 'shared'
|
|
85
87
|
}
|
|
86
88
|
}
|
|
@@ -151,6 +153,10 @@ const swiperIndicator = computed(() => {
|
|
|
151
153
|
return swiperIndicator
|
|
152
154
|
})
|
|
153
155
|
|
|
156
|
+
/**
|
|
157
|
+
* 判断元素是否为视频/图片类型
|
|
158
|
+
* 支持字符串 URL 和对象格式(通过 type 属性或 URL 后缀判断)
|
|
159
|
+
*/
|
|
154
160
|
const getMediaType = (item: string | SwiperList, type: 'video' | 'image') => {
|
|
155
161
|
const checkType = (url: string) => (type === 'video' ? isVideoUrl(url) : isImageUrl(url))
|
|
156
162
|
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
left: 30rpx;
|
|
31
31
|
|
|
32
32
|
&::after {
|
|
33
|
-
margin-left:
|
|
33
|
+
margin-left: $-spacing-4;
|
|
34
34
|
border-width: 2rpx 0 0 2rpx;
|
|
35
35
|
transform: translate(-50%, -50%) rotateZ(-45deg);
|
|
36
36
|
}
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
@include m(fraction) {
|
|
56
|
-
padding: 0
|
|
56
|
+
padding: 0 $-spacing-16;
|
|
57
57
|
height: $-swiper-nav-fraction-height;
|
|
58
58
|
line-height: $-swiper-nav-fraction-height;
|
|
59
59
|
border-radius: calc($-swiper-nav-fraction-height / 2);
|
|
@@ -69,11 +69,11 @@
|
|
|
69
69
|
height: $-swiper-nav-dot-size;
|
|
70
70
|
background: $-swiper-nav-dot-color;
|
|
71
71
|
border-radius: $-radius-circle;
|
|
72
|
-
margin: 0
|
|
72
|
+
margin: 0 $-spacing-12;
|
|
73
73
|
transition: all 0.4s ease-in;
|
|
74
74
|
|
|
75
75
|
@include when(vertical) {
|
|
76
|
-
margin:
|
|
76
|
+
margin: $-spacing-12 0;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
@include when(active) {
|
|
@@ -6,10 +6,13 @@
|
|
|
6
6
|
position: relative;
|
|
7
7
|
width: $-switch-width;
|
|
8
8
|
height: $-switch-height;
|
|
9
|
+
vertical-align: middle;
|
|
10
|
+
line-height: 1;
|
|
11
|
+
box-sizing: border-box;
|
|
9
12
|
border-radius: $-switch-circle-size;
|
|
10
13
|
background: $-switch-inactive-color;
|
|
11
14
|
font-size: $-switch-size;
|
|
12
|
-
transition: all
|
|
15
|
+
transition: all $-transition-duration-slow;
|
|
13
16
|
|
|
14
17
|
@include e(checkbox) {
|
|
15
18
|
position: absolute;
|
|
@@ -28,7 +31,7 @@
|
|
|
28
31
|
left: 4rpx;
|
|
29
32
|
background: $-switch-circle-bg;
|
|
30
33
|
border-radius: $-radius-circle;
|
|
31
|
-
transition: left
|
|
34
|
+
transition: left $-transition-duration-slow ease-out;
|
|
32
35
|
box-shadow: 0 4rpx 8rpx 0 $-switch-inactive-shadow-color;
|
|
33
36
|
|
|
34
37
|
&::after {
|
|
@@ -53,6 +56,6 @@
|
|
|
53
56
|
}
|
|
54
57
|
}
|
|
55
58
|
@include when(disabled) {
|
|
56
|
-
opacity: $-opacity-
|
|
59
|
+
opacity: $-opacity-disabled;
|
|
57
60
|
}
|
|
58
61
|
}
|
|
@@ -8,7 +8,9 @@ export default {
|
|
|
8
8
|
name: 'oxy-switch',
|
|
9
9
|
options: {
|
|
10
10
|
addGlobalClass: true,
|
|
11
|
+
// #ifndef MP-TOUTIAO
|
|
11
12
|
virtualHost: true,
|
|
13
|
+
// #endif
|
|
12
14
|
styleIsolation: 'shared'
|
|
13
15
|
}
|
|
14
16
|
}
|
|
@@ -45,6 +47,10 @@ const circleStyle = computed(() => {
|
|
|
45
47
|
return circleStyle
|
|
46
48
|
})
|
|
47
49
|
|
|
50
|
+
/**
|
|
51
|
+
* 切换开关状态。
|
|
52
|
+
* 支持 beforeChange 异步校验,通过 resolve(true/false) 决定是否执行切换。
|
|
53
|
+
*/
|
|
48
54
|
function switchValue() {
|
|
49
55
|
if (props.disabled) return
|
|
50
56
|
const newVal = props.modelValue === props.activeValue ? props.inactiveValue : props.activeValue
|
|
@@ -69,6 +75,10 @@ function switchValue() {
|
|
|
69
75
|
}
|
|
70
76
|
}
|
|
71
77
|
|
|
78
|
+
/**
|
|
79
|
+
* 初始化时校验 modelValue 是否在 activeValue/inactiveValue 范围内,
|
|
80
|
+
* 不在范围内则重置为 inactiveValue。
|
|
81
|
+
*/
|
|
72
82
|
onBeforeMount(() => {
|
|
73
83
|
if ([props.activeValue, props.inactiveValue].indexOf(props.modelValue) === -1) {
|
|
74
84
|
emit('update:modelValue', props.inactiveValue)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view :class="`oxy-tab ${customClass}`" :style="
|
|
3
|
-
<view :class="['oxy-tab__body', { 'oxy-tab__body--inactive': !active }]" v-if="shouldBeRender" :style="
|
|
2
|
+
<view :class="`oxy-tab ${customClass}`" :style="tabStyle">
|
|
3
|
+
<view :class="['oxy-tab__body', { 'oxy-tab__body--inactive': !active }]" v-if="shouldBeRender" :style="tabStyle">
|
|
4
4
|
<slot />
|
|
5
5
|
</view>
|
|
6
6
|
</view>
|
|
@@ -10,7 +10,9 @@ export default {
|
|
|
10
10
|
name: 'oxy-tab',
|
|
11
11
|
options: {
|
|
12
12
|
addGlobalClass: true,
|
|
13
|
+
// #ifndef MP-TOUTIAO
|
|
13
14
|
virtualHost: true,
|
|
15
|
+
// #endif
|
|
14
16
|
styleIsolation: 'shared'
|
|
15
17
|
}
|
|
16
18
|
}
|
|
@@ -30,17 +32,17 @@ const { parent: tabs, index } = useParent(TABS_KEY)
|
|
|
30
32
|
|
|
31
33
|
// 激活项下标
|
|
32
34
|
const active = computed(() => {
|
|
33
|
-
return isDef(tabs) ? tabs.state.activeIndex === index.value : false
|
|
35
|
+
return isDef(tabs.value) ? tabs.value.state.activeIndex === index.value : false
|
|
34
36
|
})
|
|
35
37
|
|
|
36
|
-
const painted = ref<boolean>(active.value) // 初始状态tab不会渲染,必须通过tabs来设置painted使tab渲染
|
|
38
|
+
const painted = ref<boolean>(active.value) // 初始状态tab不会渲染,必须通过tabs.value来设置painted使tab渲染
|
|
37
39
|
|
|
38
|
-
const
|
|
40
|
+
const tabStyle = computed(() => {
|
|
39
41
|
const style: CSSProperties = {}
|
|
40
|
-
if (!active.value && (!isDef(tabs) || !tabs.props.animated)) {
|
|
42
|
+
if (!active.value && (!isDef(tabs.value) || !tabs.value.props.animated)) {
|
|
41
43
|
style.display = 'none'
|
|
42
44
|
}
|
|
43
|
-
return objToStyle(style)
|
|
45
|
+
return `${objToStyle(style)}${props.customStyle}`
|
|
44
46
|
})
|
|
45
47
|
|
|
46
48
|
const shouldBeRender = computed(() => !props.lazy || painted.value || active.value)
|
|
@@ -56,7 +58,7 @@ watch(
|
|
|
56
58
|
console.error('[Oxy ui] error(oxy-tab): the type of name should be number or string')
|
|
57
59
|
return
|
|
58
60
|
}
|
|
59
|
-
if (tabs) {
|
|
61
|
+
if (tabs.value) {
|
|
60
62
|
checkName(proxy)
|
|
61
63
|
}
|
|
62
64
|
},
|
|
@@ -75,8 +77,8 @@ function checkName(self: any) {
|
|
|
75
77
|
if (myName === undefined || myName === null || myName === '') {
|
|
76
78
|
return
|
|
77
79
|
}
|
|
78
|
-
tabs &&
|
|
79
|
-
tabs.children.forEach((child: any) => {
|
|
80
|
+
tabs.value &&
|
|
81
|
+
tabs.value.children.forEach((child: any) => {
|
|
80
82
|
if (child.$.uid !== self.$.uid && child.name === myName) {
|
|
81
83
|
console.error(`The tab's bound value: ${myName} has been used`)
|
|
82
84
|
}
|
|
@@ -15,7 +15,9 @@ export default {
|
|
|
15
15
|
name: 'oxy-tabbar',
|
|
16
16
|
options: {
|
|
17
17
|
addGlobalClass: true,
|
|
18
|
+
// #ifndef MP-TOUTIAO
|
|
18
19
|
virtualHost: true,
|
|
20
|
+
// #endif
|
|
19
21
|
styleIsolation: 'shared'
|
|
20
22
|
}
|
|
21
23
|
}
|
|
@@ -92,6 +94,9 @@ function handleWindowResize() {
|
|
|
92
94
|
|
|
93
95
|
useWindowResize(handleWindowResize)
|
|
94
96
|
|
|
97
|
+
/**
|
|
98
|
+
* 计算占位高度。fixed 模式下查询 tabbar 的 rect,计算底部占用高度并转换为 rpx,用于占位撑开内容。
|
|
99
|
+
*/
|
|
95
100
|
function setPlaceholderHeight() {
|
|
96
101
|
if (!props.fixed || !props.placeholder) {
|
|
97
102
|
placeholderHeight.value = ''
|
|
@@ -22,7 +22,9 @@ export default {
|
|
|
22
22
|
name: 'oxy-tabbar-item',
|
|
23
23
|
options: {
|
|
24
24
|
addGlobalClass: true,
|
|
25
|
+
// #ifndef MP-TOUTIAO
|
|
25
26
|
virtualHost: true,
|
|
27
|
+
// #endif
|
|
26
28
|
styleIsolation: 'shared'
|
|
27
29
|
}
|
|
28
30
|
}
|
|
@@ -61,12 +63,12 @@ const customBadgeProps = computed(() => {
|
|
|
61
63
|
|
|
62
64
|
const textStyle = computed(() => {
|
|
63
65
|
const style: CSSProperties = {}
|
|
64
|
-
if (tabbar) {
|
|
65
|
-
if (active.value && tabbar.props.activeColor) {
|
|
66
|
-
style['color'] = tabbar.props.activeColor
|
|
66
|
+
if (tabbar.value) {
|
|
67
|
+
if (active.value && tabbar.value.props.activeColor) {
|
|
68
|
+
style['color'] = tabbar.value.props.activeColor
|
|
67
69
|
}
|
|
68
|
-
if (!active.value && tabbar.props.inactiveColor) {
|
|
69
|
-
style['color'] = tabbar.props.inactiveColor
|
|
70
|
+
if (!active.value && tabbar.value.props.inactiveColor) {
|
|
71
|
+
style['color'] = tabbar.value.props.inactiveColor
|
|
70
72
|
}
|
|
71
73
|
}
|
|
72
74
|
|
|
@@ -75,8 +77,8 @@ const textStyle = computed(() => {
|
|
|
75
77
|
|
|
76
78
|
const active = computed(() => {
|
|
77
79
|
const name = isDef(props.name) ? props.name : index.value
|
|
78
|
-
if (tabbar) {
|
|
79
|
-
if (tabbar.props.modelValue === name) {
|
|
80
|
+
if (tabbar.value) {
|
|
81
|
+
if (tabbar.value.props.modelValue === name) {
|
|
80
82
|
return true
|
|
81
83
|
} else {
|
|
82
84
|
return false
|
|
@@ -87,11 +89,11 @@ const active = computed(() => {
|
|
|
87
89
|
})
|
|
88
90
|
|
|
89
91
|
/**
|
|
90
|
-
* 点击tabbar选项
|
|
92
|
+
* 点击 tabbar 选项
|
|
91
93
|
*/
|
|
92
94
|
function handleClick() {
|
|
93
95
|
const name: string | number = isDef(props.name) ? props.name : index.value
|
|
94
|
-
tabbar && tabbar.setChange({ name })
|
|
96
|
+
tabbar.value && tabbar.value.setChange({ name })
|
|
95
97
|
}
|
|
96
98
|
</script>
|
|
97
99
|
<style lang="scss" scoped>
|
|
@@ -112,7 +112,9 @@ export default {
|
|
|
112
112
|
name: 'oxy-table',
|
|
113
113
|
options: {
|
|
114
114
|
addGlobalClass: true,
|
|
115
|
+
// #ifndef MP-TOUTIAO
|
|
115
116
|
virtualHost: true,
|
|
117
|
+
// #endif
|
|
116
118
|
styleIsolation: 'shared'
|
|
117
119
|
}
|
|
118
120
|
}
|
|
@@ -165,6 +167,9 @@ const tableStyle = computed(() => {
|
|
|
165
167
|
return `${objToStyle(style)}${props.customStyle}`
|
|
166
168
|
})
|
|
167
169
|
|
|
170
|
+
/**
|
|
171
|
+
* 表格实际宽度样式:根据所有列宽计算总宽度
|
|
172
|
+
*/
|
|
168
173
|
const realWidthStyle = computed(() => {
|
|
169
174
|
const style: CSSProperties = {
|
|
170
175
|
display: 'flex'
|
|
@@ -177,6 +182,9 @@ const realWidthStyle = computed(() => {
|
|
|
177
182
|
return objToStyle(style)
|
|
178
183
|
})
|
|
179
184
|
|
|
185
|
+
/**
|
|
186
|
+
* 表体高度样式:根据 rowHeight 和数据量计算
|
|
187
|
+
*/
|
|
180
188
|
const bodyStyle = computed(() => {
|
|
181
189
|
const style: CSSProperties = {}
|
|
182
190
|
if (isDef(props.height)) {
|
|
@@ -21,7 +21,9 @@ export default {
|
|
|
21
21
|
name: 'oxy-table-col',
|
|
22
22
|
options: {
|
|
23
23
|
addGlobalClass: true,
|
|
24
|
+
// #ifndef MP-TOUTIAO
|
|
24
25
|
virtualHost: true,
|
|
26
|
+
// #endif
|
|
25
27
|
styleIsolation: 'shared'
|
|
26
28
|
}
|
|
27
29
|
}
|
|
@@ -41,8 +43,8 @@ const sortDirection = ref<SortDirection>(0) // 排序方向
|
|
|
41
43
|
|
|
42
44
|
// 是否开启斑马纹
|
|
43
45
|
const stripe = computed(() => {
|
|
44
|
-
if (isDef(table)) {
|
|
45
|
-
return table.props.stripe
|
|
46
|
+
if (isDef(table.value)) {
|
|
47
|
+
return table.value.props.stripe
|
|
46
48
|
} else {
|
|
47
49
|
return false
|
|
48
50
|
}
|
|
@@ -52,8 +54,8 @@ const stripe = computed(() => {
|
|
|
52
54
|
* 是否有边框
|
|
53
55
|
*/
|
|
54
56
|
const border = computed(() => {
|
|
55
|
-
if (isDef(table)) {
|
|
56
|
-
return table.props.border
|
|
57
|
+
if (isDef(table.value)) {
|
|
58
|
+
return table.value.props.border
|
|
57
59
|
} else {
|
|
58
60
|
return false
|
|
59
61
|
}
|
|
@@ -63,8 +65,8 @@ const border = computed(() => {
|
|
|
63
65
|
* 是否超出省略
|
|
64
66
|
*/
|
|
65
67
|
const ellipsis = computed(() => {
|
|
66
|
-
if (isDef(table)) {
|
|
67
|
-
return table.props.ellipsis
|
|
68
|
+
if (isDef(table.value)) {
|
|
69
|
+
return table.value.props.ellipsis
|
|
68
70
|
} else {
|
|
69
71
|
return false
|
|
70
72
|
}
|
|
@@ -75,8 +77,8 @@ const ellipsis = computed(() => {
|
|
|
75
77
|
*/
|
|
76
78
|
const isLastFixed = computed(() => {
|
|
77
79
|
let isLastFixed: boolean = false
|
|
78
|
-
if (props.fixed && isDef(table)) {
|
|
79
|
-
isLastFixed = table.getIsLastFixed(props)
|
|
80
|
+
if (props.fixed && isDef(table.value)) {
|
|
81
|
+
isLastFixed = table.value.getIsLastFixed(props)
|
|
80
82
|
}
|
|
81
83
|
return isLastFixed
|
|
82
84
|
})
|
|
@@ -89,8 +91,8 @@ const columnStyle = computed(() => {
|
|
|
89
91
|
if (isDef(props.width)) {
|
|
90
92
|
style['width'] = withDefaultUnit(props.width)
|
|
91
93
|
}
|
|
92
|
-
if (props.fixed && isDef(table) && isFunction(table.getFixedStyle)) {
|
|
93
|
-
style = table.getFixedStyle(columnIndex.value, style)
|
|
94
|
+
if (props.fixed && isDef(table.value) && isFunction(table.value.getFixedStyle)) {
|
|
95
|
+
style = table.value.getFixedStyle(columnIndex.value, style)
|
|
94
96
|
}
|
|
95
97
|
return style
|
|
96
98
|
})
|
|
@@ -100,23 +102,23 @@ const columnStyle = computed(() => {
|
|
|
100
102
|
*/
|
|
101
103
|
const cellStyle = computed(() => {
|
|
102
104
|
let style: CSSProperties = {}
|
|
103
|
-
const rowHeight: string | number = isDef(table) && isDef(table.props) ? table.props.rowHeight : 50 // 自定义行高
|
|
105
|
+
const rowHeight: string | number = isDef(table.value) && isDef(table.value.props) ? table.value.props.rowHeight : 50 // 自定义行高
|
|
104
106
|
if (isDef(rowHeight)) {
|
|
105
107
|
style['height'] = withDefaultUnit(rowHeight)
|
|
106
108
|
}
|
|
107
|
-
if (props.fixed && isDef(table) && isFunction(table.getFixedStyle)) {
|
|
108
|
-
style = table.getFixedStyle(columnIndex.value, style)
|
|
109
|
+
if (props.fixed && isDef(table.value) && isFunction(table.value.getFixedStyle)) {
|
|
110
|
+
style = table.value.getFixedStyle(columnIndex.value, style)
|
|
109
111
|
}
|
|
110
112
|
return objToStyle(style)
|
|
111
113
|
})
|
|
112
114
|
|
|
113
115
|
// 列数据
|
|
114
116
|
const column = computed(() => {
|
|
115
|
-
if (!isDef(table) || !isDef(table.props) || !isDef(table.props.data) || !Array.isArray(table.props.data)) {
|
|
117
|
+
if (!isDef(table.value) || !isDef(table.value.props) || !isDef(table.value.props.data) || !Array.isArray(table.value.props.data)) {
|
|
116
118
|
return []
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
const column: any[] = table.props.data.map((item) => {
|
|
121
|
+
const column: any[] = table.value.props.data.map((item) => {
|
|
120
122
|
return item[props.prop]
|
|
121
123
|
})
|
|
122
124
|
return column
|
|
@@ -127,18 +129,18 @@ const column = computed(() => {
|
|
|
127
129
|
* @param index 行下标
|
|
128
130
|
*/
|
|
129
131
|
function handleRowClick(index: number) {
|
|
130
|
-
if (!isDef(table)) {
|
|
132
|
+
if (!isDef(table.value)) {
|
|
131
133
|
return
|
|
132
134
|
}
|
|
133
|
-
isFunction(table.rowClick) && table.rowClick(index)
|
|
135
|
+
isFunction(table.value.rowClick) && table.value.rowClick(index)
|
|
134
136
|
}
|
|
135
137
|
|
|
136
138
|
// 行数据
|
|
137
139
|
function getScope(index: number) {
|
|
138
|
-
if (!isDef(table) || !isDef(table.props) || !isDef(table.props.data) || !Array.isArray(table.props.data)) {
|
|
140
|
+
if (!isDef(table.value) || !isDef(table.value.props) || !isDef(table.value.props.data) || !Array.isArray(table.value.props.data)) {
|
|
139
141
|
return {}
|
|
140
142
|
}
|
|
141
|
-
return table.props.data[index] || {}
|
|
143
|
+
return table.value.props.data[index] || {}
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
defineExpose({ sortDirection: sortDirection })
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
height: $-tabs-nav-height;
|
|
101
101
|
font-size: $-tabs-nav-fs;
|
|
102
102
|
color: $-tabs-nav-color;
|
|
103
|
-
transition: color
|
|
103
|
+
transition: color $-transition-duration-slow;
|
|
104
104
|
|
|
105
105
|
@include when(active) {
|
|
106
106
|
font-weight: $-fw-semibold;
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
position: absolute;
|
|
128
128
|
bottom: 8rpx;
|
|
129
129
|
left: 0;
|
|
130
|
-
z-index:
|
|
130
|
+
z-index: $-z-index-sticky;
|
|
131
131
|
height: $-tabs-nav-line-height;
|
|
132
132
|
width: $-tabs-nav-line-width;
|
|
133
133
|
background: $-tabs-nav-line-bg-color;
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
top: 0;
|
|
179
179
|
left: 0;
|
|
180
180
|
right: 0;
|
|
181
|
-
z-index:
|
|
181
|
+
z-index: $-z-index-sticky;
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
@include e(map-btn) {
|
|
@@ -190,7 +190,7 @@
|
|
|
190
190
|
line-height: $-tabs-nav-height;
|
|
191
191
|
text-align: center;
|
|
192
192
|
color: $-tabs-nav-map-arrow-color;
|
|
193
|
-
z-index:
|
|
193
|
+
z-index: $-z-index-sticky;
|
|
194
194
|
background: $-tabs-nav-bg;
|
|
195
195
|
-webkit-tap-highlight-color: transparent;
|
|
196
196
|
|
|
@@ -207,7 +207,7 @@
|
|
|
207
207
|
|
|
208
208
|
@include e(map-arrow) {
|
|
209
209
|
display: block;
|
|
210
|
-
transition: transform
|
|
210
|
+
transition: transform $-transition-duration-slow;
|
|
211
211
|
|
|
212
212
|
@include when(open) {
|
|
213
213
|
transform: rotate(180deg);
|
|
@@ -221,23 +221,23 @@
|
|
|
221
221
|
line-height: $-tabs-nav-height;
|
|
222
222
|
font-size: $-tabs-nav-map-fs;
|
|
223
223
|
color: $-tabs-nav-map-color;
|
|
224
|
-
transition: opacity
|
|
224
|
+
transition: opacity $-transition-duration-slow;
|
|
225
225
|
background: $-tabs-nav-bg;
|
|
226
226
|
opacity: 0;
|
|
227
227
|
|
|
228
228
|
@include halfPixelBorder;
|
|
229
229
|
|
|
230
230
|
&::after {
|
|
231
|
-
z-index:
|
|
231
|
+
z-index: $-z-index-sticky;
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
@include e(map-body) {
|
|
236
236
|
display: flex;
|
|
237
237
|
flex-wrap: wrap;
|
|
238
|
-
padding:
|
|
238
|
+
padding: $-spacing-40 $-spacing-32 $-spacing-24;
|
|
239
239
|
background: $-tabs-nav-bg;
|
|
240
|
-
transition: transform
|
|
240
|
+
transition: transform $-transition-duration-slow;
|
|
241
241
|
transform: scaleY(0);
|
|
242
242
|
transform-origin: center top;
|
|
243
243
|
|
|
@@ -274,7 +274,7 @@
|
|
|
274
274
|
color: $-tabs-nav-map-color;
|
|
275
275
|
font-size: $-tabs-nav-map-fs;
|
|
276
276
|
text-align: center;
|
|
277
|
-
transition: color
|
|
277
|
+
transition: color $-transition-duration-slow, border-color $-transition-duration-slow;
|
|
278
278
|
|
|
279
279
|
@include when(active) {
|
|
280
280
|
color: $-tabs-nav-active-color;
|
|
@@ -296,7 +296,7 @@
|
|
|
296
296
|
bottom: 0;
|
|
297
297
|
background: $-tabs-nav-map-modal-bg;
|
|
298
298
|
opacity: 0;
|
|
299
|
-
transition: opacity
|
|
299
|
+
transition: opacity $-transition-duration-slow;
|
|
300
300
|
}
|
|
301
301
|
|
|
302
302
|
@include when(slide) {
|
|
@@ -169,7 +169,9 @@ export default {
|
|
|
169
169
|
name: 'oxy-tabs',
|
|
170
170
|
options: {
|
|
171
171
|
addGlobalClass: true,
|
|
172
|
+
// #ifndef MP-TOUTIAO
|
|
172
173
|
virtualHost: true,
|
|
174
|
+
// #endif
|
|
173
175
|
styleIsolation: 'shared'
|
|
174
176
|
}
|
|
175
177
|
}
|
|
@@ -326,6 +328,9 @@ onMounted(() => {
|
|
|
326
328
|
})
|
|
327
329
|
})
|
|
328
330
|
|
|
331
|
+
/**
|
|
332
|
+
* 切换 Tab Map(全部标签面板)的显隐,带淡入淡出动画
|
|
333
|
+
*/
|
|
329
334
|
function toggleMap() {
|
|
330
335
|
if (state.mapShow) {
|
|
331
336
|
state.animating = false
|
|
@@ -390,6 +395,10 @@ function setActiveTab() {
|
|
|
390
395
|
}
|
|
391
396
|
}
|
|
392
397
|
|
|
398
|
+
/**
|
|
399
|
+
* scroll-view 滚动到 active tab 居中位置。
|
|
400
|
+
* 若计算位置与当前相同,加微小随机偏移强制触发 scroll-view 重滚动。
|
|
401
|
+
*/
|
|
393
402
|
function scrollIntoView() {
|
|
394
403
|
if (!state.inited) return
|
|
395
404
|
Promise.all([getRect($item, true, proxy), getRect($container, false, proxy)]).then(([navItemsRects, navRect]) => {
|
|
@@ -438,6 +447,9 @@ function onTouchMove(event: any) {
|
|
|
438
447
|
if (!props.swipeable) return
|
|
439
448
|
touch.touchMove(event)
|
|
440
449
|
}
|
|
450
|
+
/**
|
|
451
|
+
* 触摸滑动结束:检测水平滑动方向和距离,满足阈值则切换 tab
|
|
452
|
+
*/
|
|
441
453
|
function onTouchEnd() {
|
|
442
454
|
if (!props.swipeable) return
|
|
443
455
|
const { direction, deltaX, offsetX } = touch
|
|
@@ -450,6 +462,11 @@ function onTouchEnd() {
|
|
|
450
462
|
}
|
|
451
463
|
}
|
|
452
464
|
}
|
|
465
|
+
/**
|
|
466
|
+
* 根据 modelValue 查找对应的 tabs 索引
|
|
467
|
+
* number 类型:直接使用(超出范围则回退到 0)
|
|
468
|
+
* string 类型:通过 children.name 匹配(匹配不到回退到 0)
|
|
469
|
+
*/
|
|
453
470
|
function getActiveIndex(value: number | string) {
|
|
454
471
|
// name代表的索引超过了children长度的边界,自动用0兜底
|
|
455
472
|
if (isNumber(value) && value >= children.length) {
|