UNPKG

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
!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 };