y-design-ssr
Version:
SSR component library of YUI with Vue3
393 lines (392 loc) • 10.7 kB
JavaScript
import { ref as d, reactive as J, defineComponent as F, createVNode as i, computed as S, onMounted as K, onUpdated as Q, nextTick as X, onUnmounted as Z, createTextVNode as ee } from "vue";
const te = (e) => (n) => Object.prototype.toString.call(n) === `[object ${e}]`, ne = te("Number"), _ = (e, n) => n ? typeof n == "string" ? ` ${e}--${n}` : Array.isArray(n) ? n.reduce((u, l) => u + _(e, l), "") : Object.keys(n).reduce(
(u, l) => u + (n[l] ? _(e, l) : ""),
""
) : "", ae = (e) => (n, u) => {
let l = n, f = u;
return l && typeof l != "string" && (f = l, l = ""), l = l ? `${e}__${l}` : e, `${l}${_(l, f)}`;
}, le = () => (e, n) => n ? `${_(`y-${e}`, n)}` : `y-${e}`, re = {
"pull-refresh": {
pulling: "下拉刷新...",
loosing: "释放刷新...",
loading: "数据加载中...",
success: "数据已更新",
failed: "数据跟新失败,请稍后再试"
},
"form-item": {
validateMessage: "请输入正确内容"
}
};
d("zh-CN");
J({
"zh-CN": re
});
const P = (e) => {
const n = `y-${e}`;
return [n, ae(n), le()];
}, H = (e) => isNaN(Number(e)) && typeof e == "string" ? e : `${e}px`, ie = (e) => {
switch (e) {
case "top":
return "column-reverse";
case "bottom":
return "column";
case "left":
return "row-reverse";
case "right":
return "row";
default:
return "column";
}
}, [ue, R] = P("loading"), oe = {
// Loading icon 的颜色
color: {
type: String,
default: ""
},
// 背景色
bgColor: {
type: String,
default: ""
},
bgBorderRadius: {
type: [Number, String],
default: "16px"
},
// 粗细
thick: {
type: [Number, String],
default: 8
},
// 方向
direction: {
type: String,
default: "forward"
},
// 大小
size: {
type: [Number, String],
default: "24px"
},
padding: {
type: [Number, String],
default: ""
},
// 文案
text: {
type: String,
default: ""
},
// 文案位置
textLocation: {
type: String,
default: "bottom"
},
// 文案大小
textSize: {
type: [Number, String],
default: ""
},
// 文案颜色
textColor: {
type: String,
default: ""
},
// 布局位置
position: {
type: String,
default: "relative"
}
}, ce = /* @__PURE__ */ F({
name: ue,
props: oe,
setup(e, {
slots: n
}) {
return () => {
var w, B;
const {
position: u,
textLocation: l,
bgColor: f,
bgBorderRadius: h,
size: o,
padding: x,
color: v,
thick: T,
direction: C,
text: s,
textColor: p,
textSize: r
} = e, k = ((w = n.default) == null ? void 0 : w.call(n)) || s;
return i("div", {
class: R({
[u]: u !== "relative"
})
}, [i("div", {
class: R("bg", {
[u]: u !== "relative"
}),
style: {
flexDirection: ie(l),
backgroundColor: f,
borderRadius: H(h),
padding: H(x)
}
}, [i("span", {
class: R("icon-wrapper"),
style: {
width: H(o),
height: H(o)
}
}, [((B = n.icon) == null ? void 0 : B.call(n)) || i("svg", {
class: R("icon", {
[C]: C
}),
viewBox: "25 25 50 50"
}, [i("circle", {
class: R("icon-circle"),
style: {
stroke: v,
strokeWidth: H(T)
},
cx: "50",
cy: "50",
r: "20",
fill: "none"
}, null)])]), k && i("span", {
class: R("text", {
[l]: l
}),
style: {
color: p,
fontSize: H(r)
}
}, [k])])]);
};
}
}), [se, m] = P("list"), de = /* @__PURE__ */ F({
name: se,
props: {
// 加载中 文案
loadingText: {
type: String,
default: "加载中..."
},
// 加载完成 文案
finishedText: {
type: String,
default: "没有更多了~"
},
// 加载失败 文案
errorText: {
type: String,
default: "请求失败,点击重新加载"
},
// 容器高度
height: {
type: [Number, String],
default: "auto"
},
// 唯一键名称
keyName: {
type: String,
default: "_index"
},
// 列表数组
dataSource: {
type: Array,
default: () => []
},
// 是否在初始化时立即执行滚动位置检查
immediateCheck: {
type: Boolean,
default: !0
},
// 滚动条与底部距离小于多少时触发加载
loadOffset: {
type: Number,
default: 300
},
// 是否使用虚拟列表
virtual: {
type: Boolean,
default: !1
},
// 缓冲区比例
bufferScale: {
type: Number,
default: 1
},
// 列表子项预估高度
itemHeight: {
type: [String, Number],
default: "80"
},
// 是否是不定高度子项
dynamicItemHeight: {
type: Boolean,
default: !1
}
},
emits: ["load"],
setup(e, {
slots: n,
emit: u,
expose: l
}) {
const f = d(0), h = d(!1), o = d("normal"), x = d(), v = d(), T = d(), C = d([]), s = d(0), p = d(0), r = d([]), k = S(() => ne(e.height) ? `${e.height}px` : e.height), w = S(() => r.value.length ? r.value[r.value.length - 1].bottom : 0), B = S(() => {
if (e.virtual) {
const t = s.value - M.value, a = p.value + V.value;
return E.value.slice(t, a);
}
return E.value;
}), M = S(() => Math.min(s.value, e.bufferScale * $.value)), V = S(() => Math.min(e.dataSource.length - p.value, e.bufferScale * $.value)), $ = S(() => Math.ceil(f.value / parseInt(String(e.itemHeight)))), E = S(() => e.dataSource.map((t, a) => (t[e.keyName] = a, t))), A = () => h.value ? document.documentElement.scrollTop || document.body.scrollTop : x.value.scrollTop, G = () => h.value ? document.documentElement.scrollHeight : x.value.scrollHeight, L = () => {
o.value !== "loading" && (o.value = "loading", u("load", (t) => {
if (o.value === "loading")
switch (t) {
case "error":
o.value = "error";
break;
case "finished":
o.value = "finished", e.virtual && D(), e.virtual && e.dynamicItemHeight && j();
break;
default:
o.value = "normal", e.virtual && (j(), e.dataSource.length < $.value + V.value && L());
}
}));
}, z = () => {
o.value === "normal" && G() - A() - f.value <= e.loadOffset && L();
}, D = () => {
r.value = E.value.map((t, a) => {
const c = parseInt(String(e.itemHeight));
return {
index: a,
height: c,
top: a * c,
bottom: (a + 1) * c
};
});
}, j = () => {
D();
for (let t = 1; t < r.value.length; t++)
r.value[t].top = r.value[t - 1].bottom, r.value[t].bottom = r.value[t].top + r.value[t].height;
}, W = (t, a) => {
let c = 0, N = t.length - 1, g = -1;
for (; c <= N; ) {
const y = Math.floor((c + N) / 2), b = t[y].bottom;
if (b === a)
return y + 1;
b < a ? c = y + 1 : b > a && ((g === -1 || g > y) && (g = y), N = y - 1);
}
return g;
}, Y = (t) => W(r.value, t), O = () => {
if (z(), e.virtual) {
const t = A();
U(t);
}
}, U = (t) => {
if (!v.value)
return;
const a = t || 0;
if (e.dynamicItemHeight) {
s.value = Y(a), p.value = s.value + $.value;
const c = r.value[s.value - M.value].top ? r.value[s.value - M.value].top : 0;
v.value.style.transform = `translate3d(0, ${c}px, 0)`;
} else {
s.value = Math.floor(a / parseInt(String(e.itemHeight))), p.value = s.value + $.value;
const c = s.value * parseInt(String(e.itemHeight)) - M.value * parseInt(String(e.itemHeight));
v.value.style.transform = `translate3d(0, ${c}px, 0)`;
}
}, q = () => {
if (!v.value || !T.value)
return;
const t = v.value.children;
t && t.length > 0 && [...t].forEach((a) => {
if (a instanceof HTMLDivElement) {
const c = a.getBoundingClientRect(), {
height: N
} = c, g = Number(a.dataset.index), b = r.value[g].height - N;
if (b) {
r.value[g].bottom -= b, r.value[g].height = N;
for (let I = g + 1; I < r.value.length; I++)
r.value[I].top = r.value[I - 1].bottom, r.value[I].bottom -= b;
}
}
});
};
return l({
...e,
checkIsScrollToBottom: z,
loadData: L
}), K(() => {
e.height !== "auto" ? (h.value = !1, f.value = x.value.clientHeight) : e.height === "auto" && (h.value = !0, f.value = document.documentElement.clientHeight, document.addEventListener("scroll", O)), e.virtual && (D(), U()), e.immediateCheck && z();
}), Q(async () => {
var t, a;
if (e.virtual && e.dynamicItemHeight) {
if (await X(), !((a = (t = v.value) == null ? void 0 : t.children) != null && a.length))
return;
q();
}
}), Z(() => {
h.value && document.removeEventListener("scroll", O);
}), () => i("div", {
ref: x,
class: `${m()} ${e.virtual ? m({
virtual: !0
}) : ""}`,
style: {
height: k.value
},
onScroll: O
}, [e.virtual && i("div", {
ref: T,
class: m("phantom"),
style: {
height: `${w.value}px`
}
}, null), i("div", {
ref: v,
class: m("content")
}, [B.value.map((t) => {
var a;
return i("div", {
ref: C,
class: m("item"),
"data-index": t._index
}, [(a = n.default) == null ? void 0 : a.call(n, {
item: t
})]);
})]), o.value === "loading" && i("div", {
class: m({
loading: !0
})
}, [n.loading ? n.loading() : i(ce, {
"text-location": "right"
}, {
default: () => [ee("加载中...")]
})]), o.value === "finished" && i("div", {
class: m({
finished: !0
})
}, [e.finishedText]), o.value === "error" && i("div", {
class: m("error"),
role: "presentation",
onClick: L
}, [e.errorText]), o.value === "normal" && i("div", {
class: m({
normal: !0
})
}, [n.normal ? n.normal() : null])]);
}
});
function fe(e) {
const n = e;
return n.install = (u) => {
const { name: l } = e;
l && u.component(l, e);
}, n;
}
const ge = fe(de);
export {
ge as default
};