You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
2.6 KiB
131 lines
2.6 KiB
<template>
|
|
<div class="scroll-wrapper" ref="scrollDOMRef">
|
|
<slot></slot>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted, onBeforeUnmount, watch, computed } from 'vue'
|
|
import { useStore } from '@/store/root'
|
|
import BScroll from '@better-scroll/core'
|
|
import ScrollBar from '@better-scroll/scroll-bar'
|
|
import ObserveImage from '@better-scroll/observe-image'
|
|
import Indicators from '@better-scroll/indicators'
|
|
|
|
BScroll.use(ScrollBar)
|
|
BScroll.use(ObserveImage)
|
|
BScroll.use(Indicators)
|
|
|
|
const props = defineProps({
|
|
list: [Array, String],
|
|
scrollbar: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
observeImage: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
stopPropagation: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
scrollX: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
refreshDelay: {
|
|
type: Number,
|
|
default: 20
|
|
},
|
|
autoTop: {
|
|
type: Boolean,
|
|
default: true
|
|
}
|
|
})
|
|
|
|
const timer = ref(null)
|
|
const _BScrollRef = ref(null)
|
|
const scrollDOMRef = ref(null)
|
|
const store = useStore()
|
|
const languageRef = computed(() => store.language)
|
|
|
|
function _initScroll() {
|
|
if (!scrollDOMRef.value) {
|
|
return
|
|
}
|
|
_BScrollRef.value = new BScroll(scrollDOMRef.value, {
|
|
click: true,
|
|
disableMouse: false,
|
|
disableTouch: false,
|
|
scrollX: props.scrollX,
|
|
stopPropagation: props.stopPropagation,
|
|
scrollbar: props.scrollbar,
|
|
observeImage: props.observeImage,
|
|
probeType: props.probeType,
|
|
indicators: scrollDOMRef.value.querySelector('#indicator')
|
|
? [{ relationElement: scrollDOMRef.value.querySelector('#indicator'), relationElementHandleElementIndex: 0 }]
|
|
: undefined
|
|
})
|
|
}
|
|
|
|
function refresh() {
|
|
_BScrollRef.value?.refresh()
|
|
}
|
|
|
|
function scrollTo(...args) {
|
|
_BScrollRef.value?.scrollTo(...args)
|
|
}
|
|
function scrollToElement(...args) {
|
|
_BScrollRef.value?.scrollToElement(...args)
|
|
}
|
|
//立即停止当前运行的滚动动画
|
|
function stop() {
|
|
_BScrollRef.value?.stop()
|
|
}
|
|
//允许滚动
|
|
function enable() {
|
|
_BScrollRef.value?.enable()
|
|
}
|
|
//禁止滚动
|
|
function disable() {
|
|
_BScrollRef.value?.disable()
|
|
}
|
|
function destroy() {
|
|
clearTimeout(timer.value)
|
|
_BScrollRef.value?.destroy()
|
|
_BScrollRef.value = null
|
|
}
|
|
|
|
onMounted(() => {
|
|
_initScroll()
|
|
})
|
|
|
|
onBeforeUnmount(destroy)
|
|
|
|
defineExpose({
|
|
_BScrollRef,
|
|
refresh,
|
|
scrollTo,
|
|
scrollToElement,
|
|
stop,
|
|
enable,
|
|
disable,
|
|
destroy
|
|
})
|
|
|
|
watch(
|
|
() => [props.list, languageRef],
|
|
() => {
|
|
clearTimeout(timer.value)
|
|
timer.value = setTimeout(() => {
|
|
props.autoTop && scrollTo(0, 0, 100)
|
|
refresh()
|
|
clearTimeout(timer.value)
|
|
}, props.refreshDelay)
|
|
},
|
|
{
|
|
deep: true
|
|
}
|
|
)
|
|
</script>
|
|
|