long-list-scroll-rem
Version:
A lightweight and high-performance Vue 3 virtual scrolling component designed to efficiently render long lists with dynamic rem-based sizing. Ideal for applications requiring smooth scrolling experiences and optimized rendering of large datasets.
138 lines (137 loc) • 4.53 kB
JavaScript
!function(){"use strict";try{if("undefined"!=typeof document){var e=document.createElement("style");e.appendChild(document.createTextNode(".container[data-v-f1e8249c]{height:100%;overflow:auto;position:relative;pointer-events:auto}.placeholder[data-v-f1e8249c]{position:absolute;left:0;top:0;right:0;z-index:-1}.card-item[data-v-f1e8249c]{overflow:hidden}")),document.head.appendChild(e)}}catch(t){console.error("vite-plugin-css-injected-by-js",t)}}();
import { ref, computed, onMounted, nextTick, createElementBlock, openBlock, createElementVNode, normalizeStyle, Fragment, renderList, unref, renderSlot } from "vue";
const _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props) {
target[key] = val;
}
return target;
};
const _sfc_main = /* @__PURE__ */ Object.assign({
name: "LongListScrollRem"
}, {
__name: "index",
props: {
listData: {
type: Array,
default: []
},
height: {
type: Number,
default: 100
},
rootfontSize: {
type: Number,
default: 0
},
key: {
type: String,
default: "id"
}
},
setup(__props, { expose: __expose }) {
let htmlFontSize = ref(16);
let itemSize = computed(() => {
return __props.height * rootFont.value;
});
let rootFont = computed(() => {
return __props.rootfontSize || htmlFontSize.value;
});
const container = ref(null);
const containerHeight = ref(0);
const renderCount = computed(() => Math.ceil(containerHeight.value / itemSize.value));
const start = ref(0);
const offset = ref(0);
const end = computed(() => start.value + renderCount.value);
const listHeight = computed(() => __props.listData.length * itemSize.value);
const renderList$1 = computed(() => {
if (__props.listData.length) {
return __props.listData.slice(start.value, end.value + 1);
} else {
return [];
}
});
const getTransform = computed(() => `translate3d(0,${offset.value}px,0)`);
onMounted(() => {
nextTick(() => {
containerHeight.value = container.value.clientHeight;
if (document) {
htmlFontSize.value = parseFloat(document.documentElement.style.fontSize);
}
});
});
function handleScroll(e) {
const scrollTop = e.target.scrollTop;
start.value = Math.floor(scrollTop / itemSize.value);
offset.value = scrollTop - scrollTop % itemSize.value;
}
function handleSrollTopSize(options = {
top: 0,
behavior: "smooth",
index: null
}) {
let { top, behavior, index } = options;
let scrollTop = top;
if (index === 0 || index > 0) {
scrollTop = index * itemSize.value;
}
container.value.scrollTo({
top: scrollTop,
behavior: behavior || "smooth"
});
}
__expose({
handleSrollTopSize
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", {
ref_key: "container",
ref: container,
class: "container",
onScroll: _cache[0] || (_cache[0] = ($event) => handleScroll($event))
}, [
createElementVNode("div", {
class: "placeholder",
style: normalizeStyle({ height: listHeight.value + "px" })
}, null, 4),
createElementVNode("div", {
class: "list-wrapper",
style: normalizeStyle({ transform: getTransform.value })
}, [
(openBlock(true), createElementBlock(Fragment, null, renderList(renderList$1.value, (item) => {
return openBlock(), createElementBlock("div", {
class: "card-item",
key: item[__props.key],
style: normalizeStyle({
height: unref(itemSize) + "px"
})
}, [
renderSlot(_ctx.$slots, "default", { item }, void 0, true)
], 4);
}), 128))
], 4)
], 544);
};
}
});
const LongListScrollRem = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-f1e8249c"]]);
LongListScrollRem.install = (app) => {
app.component(LongListScrollRem.name, LongListScrollRem);
};
const components = [
LongListScrollRem
];
const install = (app) => {
components.forEach((component) => app.component(component.name, component));
};
const vue = window.Vue;
if (typeof window !== "undefined" && vue) {
install(vue);
}
const listScroll = {
install
};
export {
LongListScrollRem,
listScroll as default
};