UNPKG

tav-ui

Version:
142 lines (137 loc) 4.21 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var vue = require('vue'); var useEventListener = require('../../../hooks/event/useEventListener2.js'); var tsxHelper = require('../../../utils/helper/tsxHelper2.js'); var types = require('./types2.js'); const prefixCls = "ta-virtual-scroll"; function convertToUnit(str, unit = "px") { if (str == null || str === "") { return void 0; } else if (isNaN(+str)) { return String(str); } else { return `${Number(str)}${unit}`; } } var VirtualScroll = vue.defineComponent({ name: "TaVirtualScroll", props: types.virtualScrollProps, setup(props, { slots }) { const wrapElRef = vue.ref(null); const state = vue.reactive({ first: 0, last: 0, scrollTop: 0 }); const getBenchRef = vue.computed(() => { return parseInt(props.bench, 10); }); const getItemHeightRef = vue.computed(() => { return parseInt(props.itemHeight, 10); }); const getFirstToRenderRef = vue.computed(() => { return Math.max(0, state.first - vue.unref(getBenchRef)); }); const getLastToRenderRef = vue.computed(() => { return Math.min((props.items || []).length, state.last + vue.unref(getBenchRef)); }); const getContainerStyleRef = vue.computed(() => { return { height: convertToUnit((props.items || []).length * vue.unref(getItemHeightRef)) }; }); const getWrapStyleRef = vue.computed(() => { const styles = {}; const height = convertToUnit(props.height); const minHeight = convertToUnit(props.minHeight); const minWidth = convertToUnit(props.minWidth); const maxHeight = convertToUnit(props.maxHeight); const maxWidth = convertToUnit(props.maxWidth); const width = convertToUnit(props.width); if (height) styles.height = height; if (minHeight) styles.minHeight = minHeight; if (minWidth) styles.minWidth = minWidth; if (maxHeight) styles.maxHeight = maxHeight; if (maxWidth) styles.maxWidth = maxWidth; if (width) styles.width = width; return styles; }); vue.watch([() => props.itemHeight, () => props.height], () => { onScroll(); }); function getLast(first) { const wrapEl = vue.unref(wrapElRef); if (!wrapEl) { return 0; } const height = parseInt((props.height || 0).toString(), 10) || wrapEl.clientHeight; return first + Math.ceil(height / vue.unref(getItemHeightRef)); } function getFirst() { return Math.floor(state.scrollTop / vue.unref(getItemHeightRef)); } function onScroll() { const wrapEl = vue.unref(wrapElRef); if (!wrapEl) { return; } state.scrollTop = wrapEl.scrollTop; state.first = getFirst(); state.last = getLast(state.first); } function renderChildren() { const { items = [] } = props; return items.slice(vue.unref(getFirstToRenderRef), vue.unref(getLastToRenderRef)).map(genChild); } function genChild(item, index) { index += vue.unref(getFirstToRenderRef); const top = convertToUnit(index * vue.unref(getItemHeightRef)); return vue.createVNode("div", { "class": `${prefixCls}__item`, "style": { top }, "key": index }, [tsxHelper.getSlot(slots, "default", { index, item })]); } vue.onMounted(() => { state.last = getLast(0); vue.nextTick(() => { const wrapEl = vue.unref(wrapElRef); if (!wrapEl) { return; } useEventListener.useEventListener({ el: wrapEl, name: "scroll", listener: onScroll, wait: 0 }); }); }); return () => vue.createVNode("div", { "class": prefixCls, "style": vue.unref(getWrapStyleRef), "ref": wrapElRef }, [vue.createVNode("div", { "class": `${prefixCls}__container`, "style": vue.unref(getContainerStyleRef) }, [renderChildren()])]); } }); exports["default"] = VirtualScroll; //# sourceMappingURL=virtual-scroll2.js.map