UNPKG

mealcomes

Version:

MealComes 用于学习前端的组件库

255 lines (254 loc) 5.54 kB
import { w as z } from "./utils-aznwSRCL.mjs"; import { defineComponent as k, ref as b, onMounted as F, onUpdated as B, createVNode as I, onBeforeMount as K, h as V } from "vue"; const H = { /** * 数据源 */ dataSource: { type: Array, required: !0, default: () => [] }, /** * 每一项数据的 key */ dataKey: { type: String, required: !0 }, /** * 渲染多少条数据 (存在真实 dom) */ keeps: { type: Number, default: 30 }, /** * 每一条数据预估高度 */ estimatedRowHeight: { type: Number, default: 80 }, /** * 每一行的数据组件 */ dataComponent: { type: [Object, Function], required: !0 }, /** * 数据渲染缓冲区 (基于视口顶部 top 的数据所在位置, top ~ top + cache 为缓冲区) * * start = 10 cache = 5 end = 20 * - 向下滚动时, 当 top 处于 10 ~ 15, 不做处理, * 当 top > 15, 将 start 赋为 15, 从而 end = 25(即往后渲染 cache 条数据) * - 向上滚动时, 当 top 处于 10 ~ 15, 不做处理, * 当 top < 10, 将 start 赋为 5, 从而 end = 15(即往前渲染 cache 条数据) */ cache: { type: Number, default: 2 } }, O = { uniqueKey: { type: [String, Number], required: !0 }, source: { type: Object, required: !0 }, component: { type: [Object, Function] } }, C = { itemResize: (t, l) => typeof l == "number" && (typeof t == "number" || typeof t == "string") }; function E(t, l) { const r = { start: 0, end: 0, padBehind: 0, padFront: 0 }; let a = 0; const c = /* @__PURE__ */ new Map(); let s = "init", f = 0, S; function m() { return s === "fixed"; } function p() { return m() ? f : S || t.estimatedRowHeight; } function i(e) { if (!e) return 0; let n = 0; for (let u = 0; u < e; u++) { const o = c.get(t.uniqueIds[u]); n += typeof o == "number" ? o : p(); } return n; } function d() { return m() ? p() * r.start : i(r.start); } function h() { return (t.uniqueIds.length - 1 - r.end) * p(); } function R(e, n) { r.start = e, r.end = n, r.padFront = d(), r.padBehind = h(), l({ ...r }); } function y(e, n) { const u = t.uniqueIds.length, o = t.keeps; u < o ? (e = 0, n = u - 1) : n - e < o - 1 && (e = n - o + 1), R(e, n); } function q() { if (m()) return Math.floor(a / p()); { let e = 0, n = t.uniqueIds.length, u = 0, o = 0; for (; e < n; ) { if (u = e + Math.floor((n - e) / 2), o = i(u), o === a) return u; o < a ? e = u + 1 : n = u - 1; } return e > 0 ? --e : 0; } } function g(e) { const n = e + t.keeps - 1; return Math.min(n, t.uniqueIds.length - 1); } function v() { const e = q(); if (e > r.start) return; const n = Math.max(0, e - t.cache); y(n, g(n)); } function x() { const e = q(); e < r.start + t.cache || y(e, g(e)); } function M(e) { const n = e < a ? "front" : "behind"; a = e, n === "front" ? v() : n === "behind" && x(); } function w(e, n) { c.set(e, n), s === "init" ? (f = n, s = "fixed") : s === "fixed" && f !== n && (s = "dynamic", f = 0), s === "dynamic" && c.size < Math.min(t.keeps, t.uniqueIds.length) && (S = Math.round( [...c.values()].reduce((u, o) => u + o, 0) / c.size )); } return y(0, t.keeps - 1), { handleScroll: M, saveSize: w }; } const N = /* @__PURE__ */ k({ name: "virtual-item", props: O, emits: C, setup(t, { emit: l }) { const r = b(); function a() { l("itemResize", t.uniqueKey, r.value.offsetHeight); } return F(() => { a(); }), B(() => { a(); }), () => { const { component: c, source: s, uniqueKey: f } = t; return c && I("div", { key: f, ref: r }, [I(c, { source: s }, null)]); }; } }), P = /* @__PURE__ */ k({ name: "mc-virtual-scroll-list", props: H, setup(t) { const l = b(null); let r; const a = () => { const { dataSource: i, dataKey: d } = t; return i.map((h) => h[d]); }, c = (i) => { l.value = i; }, s = () => { r = E({ keeps: t.keeps, cache: t.cache || Math.round(t.keeps / 3), uniqueIds: a(), estimatedRowHeight: t.estimatedRowHeight }, c); }; K(() => { s(); }); function f(i, d) { r.saveSize(i, d); } function S() { const i = [], { start: d, end: h } = l.value, { dataSource: R, dataComponent: y, dataKey: q } = t; for (let g = d; g <= h; g++) { const v = R[g], x = v[q]; v && i.push(V(N, { uniqueKey: x, source: v, component: y, onItemResize: f })); } return i; } const m = b(); function p() { if (m.value) { const i = m.value.scrollTop; r.handleScroll(i); } } return () => { const { padFront: i, padBehind: d } = l.value, h = { padding: `${i}px 0 ${d}px` }; return I("div", { onScroll: p, ref: m, style: { overflowY: "scroll" } }, [I("div", { style: h }, [S()])]); }; } }), L = z(P); export { L as M }; //# sourceMappingURL=virtual-scroll-list-otmacS0b.mjs.map