tav-ui
Version:
142 lines (137 loc) • 4.21 kB
JavaScript
;
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