init
This commit is contained in:
185
src/component/page/index.less
Normal file
185
src/component/page/index.less
Normal file
@@ -0,0 +1,185 @@
|
||||
.layui-laypage {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin: 10px 0;
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.layui-laypage > a:first-child,
|
||||
.layui-laypage > a:first-child em {
|
||||
border-radius: 2px 0 0 2px;
|
||||
}
|
||||
|
||||
.layui-laypage > a:last-child,
|
||||
.layui-laypage > a:last-child em {
|
||||
border-radius: 0 2px 2px 0;
|
||||
}
|
||||
|
||||
.layui-laypage > :first-child {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
.layui-laypage > :last-child {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
|
||||
.layui-laypage a,
|
||||
.layui-laypage button,
|
||||
.layui-laypage input,
|
||||
.layui-laypage select,
|
||||
.layui-laypage span {
|
||||
border: 1px solid var(--global-neutral-color-3);
|
||||
}
|
||||
|
||||
.layui-laypage a,
|
||||
.layui-laypage span {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
padding: 0 15px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
margin: 0 -1px 5px 0;
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.layui-laypage a:hover {
|
||||
color: var(--global-primary-color);
|
||||
}
|
||||
.layui-laypage-a-red:hover{
|
||||
color: #ff5722 !important;
|
||||
}
|
||||
|
||||
.layui-laypage-a-orange:hover{
|
||||
color: #ffb800 !important;
|
||||
}
|
||||
|
||||
.layui-laypage-a-green:hover{
|
||||
color: #009688 !important;
|
||||
}
|
||||
|
||||
.layui-laypage-a-cyan:hover{
|
||||
color: #2f4056 !important;
|
||||
}
|
||||
|
||||
.layui-laypage-a-blue:hover{
|
||||
color: #01aaed !important;
|
||||
}
|
||||
|
||||
.layui-laypage-a-black:hover{
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.layui-laypage-a-gray:hover{
|
||||
color: #c2c2c2 !important;
|
||||
}
|
||||
|
||||
.layui-laypage em {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.layui-laypage .layui-laypage-spr {
|
||||
color: #999;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.layui-laypage a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.layui-laypage .layui-laypage-curr {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.layui-laypage .layui-laypage-curr em {
|
||||
position: relative;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.layui-laypage .layui-laypage-curr .layui-laypage-em {
|
||||
position: absolute;
|
||||
left: -1px;
|
||||
top: -1px;
|
||||
padding: 1px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--global-primary-color);
|
||||
}
|
||||
|
||||
.layui-laypage-em {
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.layui-laypage-next em,
|
||||
.layui-laypage-prev em {
|
||||
font-family: Sim sun;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.layui-laypage .layui-laypage-count,
|
||||
.layui-laypage .layui-laypage-limits,
|
||||
.layui-laypage .layui-laypage-refresh,
|
||||
.layui-laypage .layui-laypage-skip {
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.layui-laypage .layui-laypage-limits,
|
||||
.layui-laypage .layui-laypage-refresh {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.layui-laypage .layui-laypage-refresh i {
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.layui-laypage select {
|
||||
height: 22px;
|
||||
padding: 3px;
|
||||
margin-top: 4px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.layui-laypage .layui-laypage-skip {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.layui-laypage button,
|
||||
.layui-laypage input {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
border-radius: 2px;
|
||||
vertical-align: top;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.layui-laypage input {
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
margin: 0 10px;
|
||||
padding: 0 3px;
|
||||
text-align: center;
|
||||
&::-webkit-outer-spin-button,
|
||||
&::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
}
|
||||
|
||||
.layui-laypage input:focus,
|
||||
.layui-laypage select:focus {
|
||||
border-color: var(--global-primary-color) !important;
|
||||
}
|
||||
|
||||
.layui-laypage button {
|
||||
margin-left: 10px;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
5
src/component/page/index.ts
Normal file
5
src/component/page/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { withInstall, WithInstallType } from "../../utils";
|
||||
import Component from "./index.vue";
|
||||
|
||||
const component: WithInstallType<typeof Component> = withInstall(Component);
|
||||
export default component;
|
||||
227
src/component/page/index.vue
Normal file
227
src/component/page/index.vue
Normal file
@@ -0,0 +1,227 @@
|
||||
<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;
|
||||
}
|
||||
|
||||
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>
|
||||
</div>
|
||||
</template>
|
||||
0
src/component/page/interface.ts
Normal file
0
src/component/page/interface.ts
Normal file
Reference in New Issue
Block a user