This commit is contained in:
2022-12-09 16:41:41 +08:00
parent c1cce5a7c2
commit ff7aa8774f
2003 changed files with 156639 additions and 140 deletions

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,216 @@
const NOOP = () => {
};
const isArray = Array.isArray;
const isFunction = (val) => typeof val === "function";
const isSymbol = (val) => typeof val === "symbol";
let activeEffectScope;
function recordEffectScope(effect, scope = activeEffectScope) {
if (scope && scope.active) {
scope.effects.push(effect);
}
}
const createDep = (effects) => {
const dep = new Set(effects);
dep.w = 0;
dep.n = 0;
return dep;
};
const wasTracked = (dep) => (dep.w & trackOpBit) > 0;
const newTracked = (dep) => (dep.n & trackOpBit) > 0;
const initDepMarkers = ({ deps }) => {
if (deps.length) {
for (let i = 0; i < deps.length; i++) {
deps[i].w |= trackOpBit;
}
}
};
const finalizeDepMarkers = (effect) => {
const { deps } = effect;
if (deps.length) {
let ptr = 0;
for (let i = 0; i < deps.length; i++) {
const dep = deps[i];
if (wasTracked(dep) && !newTracked(dep)) {
dep.delete(effect);
} else {
deps[ptr++] = dep;
}
dep.w &= ~trackOpBit;
dep.n &= ~trackOpBit;
}
deps.length = ptr;
}
};
let effectTrackDepth = 0;
let trackOpBit = 1;
const maxMarkerBits = 30;
let activeEffect;
class ReactiveEffect {
constructor(fn, scheduler = null, scope) {
this.fn = fn;
this.scheduler = scheduler;
this.active = true;
this.deps = [];
this.parent = void 0;
recordEffectScope(this, scope);
}
run() {
if (!this.active) {
return this.fn();
}
let parent = activeEffect;
let lastShouldTrack = shouldTrack;
while (parent) {
if (parent === this) {
return;
}
parent = parent.parent;
}
try {
this.parent = activeEffect;
activeEffect = this;
shouldTrack = true;
trackOpBit = 1 << ++effectTrackDepth;
if (effectTrackDepth <= maxMarkerBits) {
initDepMarkers(this);
} else {
cleanupEffect(this);
}
return this.fn();
} finally {
if (effectTrackDepth <= maxMarkerBits) {
finalizeDepMarkers(this);
}
trackOpBit = 1 << --effectTrackDepth;
activeEffect = this.parent;
shouldTrack = lastShouldTrack;
this.parent = void 0;
if (this.deferStop) {
this.stop();
}
}
}
stop() {
if (activeEffect === this) {
this.deferStop = true;
} else if (this.active) {
cleanupEffect(this);
if (this.onStop) {
this.onStop();
}
this.active = false;
}
}
}
function cleanupEffect(effect) {
const { deps } = effect;
if (deps.length) {
for (let i = 0; i < deps.length; i++) {
deps[i].delete(effect);
}
deps.length = 0;
}
}
let shouldTrack = true;
function trackEffects(dep, debuggerEventExtraInfo) {
let shouldTrack2 = false;
if (effectTrackDepth <= maxMarkerBits) {
if (!newTracked(dep)) {
dep.n |= trackOpBit;
shouldTrack2 = !wasTracked(dep);
}
} else {
shouldTrack2 = !dep.has(activeEffect);
}
if (shouldTrack2) {
dep.add(activeEffect);
activeEffect.deps.push(dep);
}
}
function triggerEffects(dep, debuggerEventExtraInfo) {
const effects = isArray(dep) ? dep : [...dep];
for (const effect of effects) {
if (effect.computed) {
triggerEffect(effect);
}
}
for (const effect of effects) {
if (!effect.computed) {
triggerEffect(effect);
}
}
}
function triggerEffect(effect, debuggerEventExtraInfo) {
if (effect !== activeEffect || effect.allowRecurse) {
if (effect.scheduler) {
effect.scheduler();
} else {
effect.run();
}
}
}
new Set(/* @__PURE__ */ Object.getOwnPropertyNames(Symbol).filter((key) => key !== "arguments" && key !== "caller").map((key) => Symbol[key]).filter(isSymbol));
function toRaw(observed) {
const raw = observed && observed["__v_raw"];
return raw ? toRaw(raw) : observed;
}
function trackRefValue(ref) {
if (shouldTrack && activeEffect) {
ref = toRaw(ref);
{
trackEffects(ref.dep || (ref.dep = createDep()));
}
}
}
function triggerRefValue(ref, newVal) {
ref = toRaw(ref);
if (ref.dep) {
{
triggerEffects(ref.dep);
}
}
}
class ComputedRefImpl {
constructor(getter, _setter, isReadonly, isSSR) {
this._setter = _setter;
this.dep = void 0;
this.__v_isRef = true;
this._dirty = true;
this.effect = new ReactiveEffect(getter, () => {
if (!this._dirty) {
this._dirty = true;
triggerRefValue(this);
}
});
this.effect.computed = this;
this.effect.active = this._cacheable = !isSSR;
this["__v_isReadonly"] = isReadonly;
}
get value() {
const self = toRaw(this);
trackRefValue(self);
if (self._dirty || !self._cacheable) {
self._dirty = false;
self._value = self.effect.run();
}
return self._value;
}
set value(newValue) {
this._setter(newValue);
}
}
function computed(getterOrOptions, debugOptions, isSSR = false) {
let getter;
let setter;
const onlyGetter = isFunction(getterOrOptions);
if (onlyGetter) {
getter = getterOrOptions;
setter = NOOP;
} else {
getter = getterOrOptions.get;
setter = getterOrOptions.set;
}
const cRef = new ComputedRefImpl(getter, setter, onlyGetter || !setter, isSSR);
return cRef;
}
export { computed as c };

View File

@@ -0,0 +1,229 @@
<script lang="ts">
export default {
name: "LayPage",
};
</script>
<script setup lang="ts">
import "./index.less";
import { Ref, ref, watch, useSlots, computed } from "vue";
import { useI18n } from "../../language";
export interface PageProps {
total: number;
limit: number;
theme?: string;
showPage?: boolean;
showSkip?: boolean;
showCount?: boolean;
showLimit?: boolean;
showInput?: boolean;
showRefresh?: boolean;
pages?: number;
limits?: number[];
modelValue?: number;
count?: number;
}
const props = withDefaults(defineProps<PageProps>(), {
limit: 10,
pages: 10,
modelValue: 1,
theme: "green",
showPage: false,
showSkip: false,
showCount: false,
showLimit: true,
showInput: false,
showRefresh: false,
limits: () => [10, 20, 30, 40, 50],
});
const { t } = useI18n();
const slots = useSlots();
const maxPage = ref(0);
const limits = ref(props.limits);
const pages = computed(() => Math.floor(props.pages / 2));
const currentPage: Ref<number> = ref(props.modelValue);
const currentPageShow: Ref<number> = ref(currentPage.value);
const inlimit = ref(props.limit);
watch(
() => props.limit,
() => {
inlimit.value = props.limit;
}
);
const totalPage = computed(() => {
maxPage.value = Math.ceil(props.total / inlimit.value);
let r: number[] = [];
// 计算 star 页
let start =
maxPage.value <= props.pages
? 1
: currentPage.value > pages.value
? maxPage.value - currentPage.value + 1 < pages.value
? currentPage.value -
(pages.value +
(pages.value - (maxPage.value - currentPage.value + 1)))
: currentPage.value - pages.value
: 1;
for (let i = start; ; i++) {
if (r.length >= props.pages || i > maxPage.value) {
break;
}
r.push(i);
}
return r;
});
const emit = defineEmits(["update:modelValue", "update:limit", "change"]);
const prev = () => {
if (currentPage.value === 1) {
return;
}
currentPage.value--;
emit("change", { current: currentPage.value, limit: inlimit.value });
};
const next = () => {
if (currentPage.value === maxPage.value || maxPage.value === 0) {
return;
}
currentPage.value++;
emit("change", { current: currentPage.value, limit: inlimit.value });
};
const jump = (page: number) => {
currentPage.value = page;
emit("change", { current: currentPage.value, limit: inlimit.value });
};
const jumpPage = () => {
currentPage.value = currentPageShow.value;
emit("change", { current: currentPage.value, limit: inlimit.value });
};
const changelimit = () => {
const maxPage = Math.ceil(props.total / inlimit.value);
if (currentPage.value > maxPage) {
currentPage.value = maxPage;
}
emit("change", { current: currentPage.value, limit: inlimit.value });
};
const refresh = () => {
emit("change", { current: currentPage.value, limit: inlimit.value });
};
watch(inlimit, () => {
emit("update:limit", inlimit.value);
});
watch(currentPage, () => {
const min = totalPage.value[0];
const max = totalPage.value[totalPage.value.length - 1];
if (currentPage.value > max) currentPage.value = max;
if (currentPage.value < min) currentPage.value = min;
currentPageShow.value = currentPage.value;
emit("update:modelValue", currentPage.value);
});
watch(
() => props.modelValue,
() => {
currentPage.value = props.modelValue;
currentPageShow.value = currentPage.value;
}
);
</script>
<template>
<div class="layui-laypage layui-laypage-default">
<span v-if="showCount" class="layui-laypage-count"
>{{ t("page.total") }} {{ total }} {{ t("page.item") }} {{ maxPage }}
{{ t("page.page") }}</span
>
<a
href="javascript:;"
class="layui-laypage-prev"
:class="[
currentPage === 1 ? 'layui-disabled' : '',
theme && currentPage !== 1 ? 'layui-laypage-a-' + theme : '',
]"
@click="prev()"
>
<slot v-if="slots.prev" name="prev"></slot>
<template v-else>{{ t("page.previous") }}</template>
</a>
<template v-if="showPage">
<template v-for="index of totalPage" :key="index">
<span v-if="index === currentPage" class="layui-laypage-curr">
<em
class="layui-laypage-em"
:class="[theme ? 'layui-bg-' + theme : '']"
></em>
<em>{{ index }}</em>
</span>
<a
v-else
href="javascript:;"
@click="jump(index)"
:class="[theme ? 'layui-laypage-a-' + theme : '']"
>{{ index }}</a
>
</template>
</template>
<a
href="javascript:;"
class="layui-laypage-next"
:class="[
currentPage === maxPage || maxPage === 0 ? 'layui-disabled' : '',
theme && currentPage !== maxPage && maxPage !== 0
? 'layui-laypage-a-' + theme
: '',
]"
@click="next()"
>
<slot v-if="slots.next" name="next"></slot>
<template v-else>{{ t("page.next") }}</template>
</a>
<span v-if="showLimit" class="layui-laypage-limits">
<select v-model="inlimit" @change="changelimit">
<option v-for="val of limits" :key="val" :value="val">
{{ val }} {{ t("page.item") }}/{{ t("page.page") }}
</option>
</select>
</span>
<a
v-if="showRefresh"
href="javascript:;"
@click="refresh"
class="layui-laypage-refresh"
>
<i class="layui-icon layui-icon-refresh"></i>
</a>
<span v-if="props.showSkip" class="layui-laypage-skip">
{{ t("page.goTo") }}
<input
v-model="currentPageShow"
@keypress.enter="jumpPage()"
type="number"
class="layui-input layui-input-number"
/>{{ t("page.page") }}
<button
type="button"
class="layui-laypage-btn"
@click="jumpPage()"
:disabled="currentPageShow > maxPage || currentPageShow == currentPage"
>
{{ t("page.confirm") }}
</button>
</span>
<span v-if="count">共{{count}}条</span>
</div>
</template>

View File

@@ -0,0 +1,65 @@
export default {
input: {
placeholder: "请输入",
},
page: {
previous: "上一页",
next: "下一页",
goTo: "到第",
confirm: "确认",
page: "页",
item: "条",
total: "共",
},
datePicker: {
year: "年",
month: "月",
sunday: "日",
monday: "一",
tuesday: "二",
wednesday: "三",
thursday: "四",
friday: "五",
saturday: "六",
january: "1月",
february: "2月",
march: "3月",
april: "4月",
may: "5月",
june: "6月",
july: "7月",
august: "8月",
september: "9月",
october: "10月",
november: "11月",
december: "12月",
selectDate: "选择日期",
selectTime: "选择时间",
selectYear: "选择年份",
selectMonth: "选择月份",
clear: "清空",
confirm: "确认",
cancel: "取消",
now: "现在",
},
empty: {
description: "无数据",
},
upload: {
text: "上传文件",
dragText: "点击上传,或将文件拖拽到此处",
defaultErrorMsg: "上传失败",
urlErrorMsg: "上传地址格式不合法",
numberErrorMsg: "文件上传超过规定的个数",
cutInitErrorMsg: "剪裁插件初始化失败",
uploadSuccess: "上传成功",
cannotSupportCutMsg:
"当前版本暂不支持单次多文件剪裁,尝试设置 multiple 为 false, 通过 @done 获取返回文件对象",
occurFileSizeErrorMsg:
"文件大小超过限制,文件最大不可超过传入的指定size属性的KB数",
startUploadMsg: "开始上传",
confirmBtn: "确认",
cancelBtn: "取消",
title: "标题",
},
};

View File

@@ -0,0 +1,40 @@
.result {
text-align: center;
}
.result .success svg {
color: #32c682;
text-align: center;
margin-top: 40px;
}
.result .failure svg {
color: #f56c6c;
text-align: center;
margin-top: 40px;
}
.result .title {
margin-top: 25px;
}
.result .desc {
margin-top: 25px;
width: 60%;
margin-left: 20%;
color: rgba(0, 0, 0, 0.45);
}
.result .content {
margin-top: 20px;
width: 80%;
border-radius: 10px;
background-color: white;
margin-left: 10%;
}
.result .extra {
padding-top: 10px;
border-top: 1px whitesmoke solid;
margin-top: 25px;
}