vue-amazing-ui
Version:
An Amazing Vue3 UI Components Library, Using TypeScript.
127 lines (126 loc) • 4.29 kB
JavaScript
import { defineComponent as _, ref as u, computed as g, watch as z, onMounted as F, createElementBlock as v, openBlock as h, normalizeStyle as I, Fragment as L, renderList as A, createBlock as B, unref as M, mergeProps as E, withCtx as N, createElementVNode as w, normalizeClass as S } from "vue";
import H from "../spin/index.js";
import { useResizeObserver as O } from "../utils/index.js";
const V = ["href", "target"], j = ["src", "alt", "onLoad"], K = /* @__PURE__ */ _({
__name: "Waterfall",
props: {
images: { default: () => [] },
columnCount: { default: 3 },
columnGap: { default: 20 },
width: { default: "100%" },
borderRadius: { default: 8 },
backgroundColor: { default: "#F2F4F8" },
spinProps: { default: () => ({}) }
},
setup(k) {
const e = k, i = u(), c = u(), p = u(Array(e.images.length).fill(!1)), m = u(), f = u([]), r = u(Array(e.columnCount).fill(0)), s = u(0), C = g(() => typeof e.width == "number" ? `${e.width}px` : e.width), G = g(() => Math.max(...r.value) + e.columnGap), b = g(() => e.images.length);
z(
() => [e.images, e.columnCount, e.columnGap, e.width],
() => {
c.value = i.value.offsetWidth, r.value = Array(e.columnCount).fill(0), s.value++, d(s.value);
},
{
deep: !0,
// 强制转成深层侦听器
flush: "post"
// 在侦听器回调中访问被 Vue 更新之后的 DOM
}
), F(() => {
c.value = i.value.offsetWidth, d(s.value);
});
function $() {
const t = i.value.offsetWidth;
e.images.length && t !== c.value && (c.value = t, s.value++, d(s.value));
}
O(i, $);
async function d(t) {
m.value = (c.value - (e.columnCount + 1) * e.columnGap) / e.columnCount, f.value = [];
for (let l = 0; l < b.value; l++)
if (t === s.value)
await W(e.images[l].src, l);
else
return !1;
}
function W(t, l) {
return new Promise((n) => {
const a = new Image();
a.src = t, a.onload = function() {
const o = a.height / (a.width / m.value);
f.value[l] = {
// 存储图片宽高和位置信息
width: m.value,
height: o,
...y(l, o)
}, n("load");
};
});
}
function y(t, l) {
if (t < e.columnCount)
return r.value[t] = e.columnGap + l, {
top: e.columnGap,
left: (m.value + e.columnGap) * t + e.columnGap
};
{
const n = Math.min(...r.value);
let a = 0;
for (let o = 0; o < e.columnCount; o++)
if (r.value[o] === n) {
a = o;
break;
}
return r.value[a] = n + e.columnGap + l, {
top: n + e.columnGap,
left: (m.value + e.columnGap) * a + e.columnGap
};
}
}
function P(t) {
p.value[t] = !0;
}
function R(t) {
if (t) {
if (t.name)
return t.name;
{
const l = t.src.split("?")[0].split("/");
return l[l.length - 1];
}
}
}
return (t, l) => (h(), v("div", {
ref_key: "waterfallRef",
ref: i,
class: "m-waterfall",
style: I(`--border-radius: ${t.borderRadius}px; background-color: ${t.backgroundColor}; width: ${C.value}; height: ${G.value}px;`)
}, [
(h(!0), v(L, null, A(f.value, (n, a) => (h(), B(M(H), E({
class: "waterfall-image",
style: `width: ${n.width}px; height: ${n.height}px; top: ${n && n.top}px; left: ${n && n.left}px;`,
spinning: !p.value[a],
size: "small",
indicator: "dynamic-circle",
ref_for: !0
}, t.spinProps, { key: a }), {
default: N(() => [
w("a", {
class: S(["image-link", { "link-cursor": t.images[a].link }]),
href: t.images[a].link,
target: t.images[a].target ? t.images[a].target : "_blank"
}, [
w("img", {
class: "image-item",
src: t.images[a].src,
alt: R(t.images[a]),
onLoad: (o) => P(a)
}, null, 40, j)
], 10, V)
]),
_: 2
}, 1040, ["style", "spinning"]))), 128))
], 4));
}
});
export {
K as default
};