1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
| <template> <div :class="{ wrapper: true, x: props.scrollX }" ref="wrapper"> <div class="content"> <slot></slot> </div> </div> </template>
<script setup lang="ts"> import { onMounted, defineProps, PropType, defineEmits } from 'vue'
import BScroll from '@better-scroll/core' import ObserveDOM from '@better-scroll/observe-dom' import ObserveImage from '@better-scroll/observe-image' import Pullup from '@better-scroll/pull-up' import Pulldown from '@better-scroll/pull-down' let bscroll: BScroll const wrapper = ref(null) BScroll.use(ObserveDOM) BScroll.use(ObserveImage) BScroll.use(Pullup) BScroll.use(Pulldown) const emit = defineEmits(['ckick', 'beforeScroll', 'afterScroll', 'scroll']) const props = defineProps({ /** * 1 滚动的时候会派发scroll事件,会截流。 * 2 滚动的时候实时派发scroll事件,不会截流。 * 3 除了实时派发scroll事件,在swipe的情况下仍然能实时派发scroll事件 */ probeType: { type: Number as PropType<1 | 2 | 3>, required: false, default: 1 },
/** * 是否开启横向滚动,默认纵向滚动。 * 开启横向滚动需要将传入元素设置为横向例如:display:inline-block */ scrollX: { type: Boolean, required: false, default: false },
/** * 点击列表是否派发click事件 */ click: { type: Boolean, default: true }, /** * 是否派发滚动事件 */ listenScroll: { type: Boolean, default: false }, /** * 是否派发滚动到底部的事件,用于上拉加载 */ pullup: { type: Function, default: null }, /** * 是否派发顶部下拉的事件,用于下拉刷新 */ pulldown: { type: Function, default: null }, /** * 是否派发列表滚动开始的事件 */ beforeScroll: { type: Boolean, default: false }, /** * 是否派发列表滚动开始的事件 */ afterScroll: { type: Boolean, default: false } })
onMounted(() => { bscroll = new BScroll(wrapper.value, { scrollX: props.scrollX, probeType: props.probeType, click: props.click, observeDOM: true, observeImage: true, mouseWheel: true, pullDownRefresh: true, pullUpLoad: true }) /** * 如果开启了滚动前事件派发 */ if (props.beforeScroll) { bscroll.on('beforeScrollStart', () => { emit('beforeScroll') }) }
/** * 如果开启了滚动(滚动中)事件派发 */ if (props.listenScroll) { bscroll.on('scroll', (position: { x: number; y: number }) => { emit('scroll', position) }) }
/** * 如果开启了滚动结束事件派发 */ if (props.beforeScroll) { bscroll.on('scrollEnd', () => { emit('afterScroll') }) }
if (props.pullup !== null) { bscroll.on('pullingUp', () => { try { props.pullup().then(() => { bscroll.finishPullUp() }) } catch (e) { // 传入非 Promise 函数 bscroll.finishPullUp() } }) }
if (props.pulldown !== null) { bscroll.on('pullingDown', () => { try { props.pulldown().then(() => { bscroll.finishPullDown() }) } catch (e) { // 传入非 Promise 函数 bscroll.finishPullDown() } }) } }) </script>
<style scoped lang="scss"> @import './index.scss'; </style>
|