Skip to content

Commit 19dc35b

Browse files
fix: 🐛 修复IndexBar索引值显示错误的问题 (#433)
Closes: #408
1 parent 4b41a51 commit 19dc35b

1 file changed

Lines changed: 35 additions & 7 deletions

File tree

src/uni_modules/wot-design-uni/components/wd-index-bar/wd-index-bar.vue

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
<!-- #ifdef MP-DINGTALK -->
44
<view class="wd-index-bar" :id="indexBarId">
55
<!-- #endif -->
6-
<scroll-view :scrollTop="scrollTop" :scroll-y="true" class="wd-index-bar__content" @scroll="hanleScroll">
6+
<scroll-view :scrollTop="scrollState.scrollTop" :scroll-y="true" class="wd-index-bar__content" @scroll="hanleScroll">
77
<slot></slot>
88
</scroll-view>
99
<view
1010
class="wd-index-bar__sidebar"
11+
@touchstart.stop.prevent="handleTouchStart"
1112
@touchmove.stop.prevent="handleTouchMove"
1213
@touchend.stop.prevent="handleTouchEnd"
1314
@touchcancel.stop.prevent="handleTouchEnd"
@@ -30,8 +31,8 @@
3031
<script setup lang="ts">
3132
import type { AnchorItem, AnchorIndex } from './type'
3233
import { indexBarInjectionKey, indexBarProps } from './type'
33-
import { ref, getCurrentInstance, onMounted, reactive } from 'vue'
34-
import { getRect, isDef, uuid } from '../common/util'
34+
import { ref, getCurrentInstance, onMounted, reactive, nextTick } from 'vue'
35+
import { getRect, isDef, uuid, requestAnimationFrame } from '../common/util'
3536
import { useChildren } from '../composables/useChildren'
3637
3738
const props = defineProps(indexBarProps)
@@ -49,7 +50,12 @@ const { linkChildren } = useChildren(indexBarInjectionKey)
4950
5051
linkChildren({ props, anchorState: state })
5152
52-
const scrollTop = ref(0)
53+
const scrollState = reactive({
54+
scrollTop: 0, // 即将滚动到的位置
55+
prevScrollTop: 0, // 上次记录的位置
56+
// 滚动距离
57+
touching: false
58+
})
5359
5460
// 组件距离页面顶部的高度
5561
let offsetTop = 0
@@ -63,7 +69,6 @@ let sidebarInfo = {
6369
function init() {
6470
setTimeout(() => {
6571
state.activeIndex = state.anchorList[0]?.index
66-
6772
Promise.all([
6873
getRect(`#${indexBarId.value}`, false, proxy),
6974
getRect('.wd-index-bar__sidebar', false, proxy),
@@ -81,6 +86,9 @@ onMounted(() => {
8186
})
8287
8388
function hanleScroll(scrollEvent: any) {
89+
if (scrollState.touching) {
90+
return
91+
}
8492
const { detail } = scrollEvent
8593
const scrolltop = Math.floor(detail.scrollTop)
8694
const anchor = state.anchorList.find((item, index) => {
@@ -91,6 +99,7 @@ function hanleScroll(scrollEvent: any) {
9199
if (state.activeIndex !== anchor.index) {
92100
state.activeIndex = anchor.index
93101
}
102+
scrollState.prevScrollTop = scrolltop
94103
}
95104
96105
function getAnchorByPageY(pageY: number) {
@@ -101,18 +110,37 @@ function getAnchorByPageY(pageY: number) {
101110
return state.anchorList[idx]
102111
}
103112
113+
function handleTouchStart() {
114+
scrollState.touching = true
115+
}
116+
104117
function handleTouchMove(e: TouchEvent) {
105118
const clientY = e.touches[0].pageY
106119
if (state.activeIndex === getAnchorByPageY(clientY).index) {
107120
return
108121
}
109122
state.activeIndex = getAnchorByPageY(clientY).index
110-
scrollTop.value = getAnchorByPageY(clientY).top - offsetTop
123+
setScrollTop(getAnchorByPageY(clientY).top - offsetTop)
111124
}
112125
113126
function handleTouchEnd(e: TouchEvent) {
114127
const clientY = e.changedTouches[0].pageY
115-
scrollTop.value = getAnchorByPageY(clientY).top - offsetTop
128+
state.activeIndex = getAnchorByPageY(clientY).index
129+
setScrollTop(getAnchorByPageY(clientY).top - offsetTop)
130+
requestAnimationFrame(() => {
131+
scrollState.touching = false
132+
})
133+
}
134+
135+
function setScrollTop(top: number) {
136+
if (scrollState.scrollTop === top) {
137+
scrollState.scrollTop = scrollState.prevScrollTop
138+
nextTick(() => {
139+
scrollState.scrollTop = top
140+
})
141+
} else {
142+
scrollState.scrollTop = top
143+
}
116144
}
117145
</script>
118146

0 commit comments

Comments
 (0)