UNPKG

@jdlinker/ui

Version:

jdLinker UI库,基于ant-design-vue封装

93 lines (80 loc) 3.1 kB
import { defineComponent, h, computed, ref, getCurrentInstance, onUnmounted, inject } from 'vue'; import { on, off } from '@jdlinker/utils'; import { renderThumbStyle, BAR_MAP } from './util'; export default defineComponent({ name: 'Bar', props: { vertical: Boolean, size: String, move: Number, }, setup(props) { const instance = getCurrentInstance(); const thumb = ref(); const wrap = inject('scroll-bar-wrap', {}) as any; const bar = computed(() => { return BAR_MAP[props.vertical ? 'vertical' : 'horizontal']; }); const barStore = ref<any>({}); const cursorDown = ref(); const clickThumbHandler = (e: any) => { // prevent click event of right button if (e.ctrlKey || e.button === 2) { return; } window.getSelection()?.removeAllRanges(); startDrag(e); barStore.value[bar.value.axis] = e.currentTarget[bar.value.offset] - (e[bar.value.client] - e.currentTarget.getBoundingClientRect()[bar.value.direction]); }; const clickTrackHandler = (e: any) => { const offset = Math.abs(e.target.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]); const thumbHalf = thumb.value[bar.value.offset] / 2; const thumbPositionPercentage = ((offset - thumbHalf) * 100) / instance?.vnode.el?.[bar.value.offset]; wrap.value[bar.value.scroll] = (thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100; }; const startDrag = (e: any) => { e.stopImmediatePropagation(); cursorDown.value = true; on(document, 'mousemove', mouseMoveDocumentHandler); on(document, 'mouseup', mouseUpDocumentHandler); document.onselectstart = () => false; }; const mouseMoveDocumentHandler = (e: any) => { if (cursorDown.value === false) return; const prevPage = barStore.value[bar.value.axis]; if (!prevPage) return; const offset = (instance?.vnode.el?.getBoundingClientRect()[bar.value.direction] - e[bar.value.client]) * -1; const thumbClickPosition = thumb.value[bar.value.offset] - prevPage; const thumbPositionPercentage = ((offset - thumbClickPosition) * 100) / instance?.vnode.el?.[bar.value.offset]; wrap.value[bar.value.scroll] = (thumbPositionPercentage * wrap.value[bar.value.scrollSize]) / 100; }; function mouseUpDocumentHandler() { cursorDown.value = false; barStore.value[bar.value.axis] = 0; off(document, 'mousemove', mouseMoveDocumentHandler); document.onselectstart = null; } onUnmounted(() => { off(document, 'mouseup', mouseUpDocumentHandler); }); return () => h( 'div', { class: ['scrollbar__bar', 'is-' + bar.value.key], onMousedown: clickTrackHandler, }, h('div', { ref: thumb, class: 'scrollbar__thumb', onMousedown: clickThumbHandler, style: renderThumbStyle({ size: props.size, move: props.move, bar: bar.value, }), }) ); }, });