feat: blog
This commit is contained in:
149
components/Pagination.vue
Normal file
149
components/Pagination.vue
Normal file
@@ -0,0 +1,149 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
const props = defineProps(['modelValue', 'pageTotal'])
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const onPrev = () => {
|
||||
if (props.modelValue <= 1) return; // 限制上一页翻页按钮的边界
|
||||
emit('update:modelValue', props.modelValue - 1)
|
||||
}
|
||||
const onNext = () => {
|
||||
if (props.modelValue >= props.pageTotal) return; // 限制下一页翻页按钮的边界
|
||||
emit('update:modelValue', props.modelValue + 1)
|
||||
}
|
||||
const setPageNum = (pageNum) => {
|
||||
if (typeof pageNum !== 'number') return; //如果pageNum不是数值类型则返回
|
||||
if (pageNum < 1) return; // 限制上一页翻页按钮的边界
|
||||
if (pageNum > props.pageTotal) return; // 限制下一页翻页按钮的边界
|
||||
emit('update:modelValue', pageNum)
|
||||
}
|
||||
|
||||
const genPageArray = (current, total, size) => {
|
||||
let arr = []
|
||||
if (total < size + 2) {
|
||||
arr = Array.from({ length: total }, (v, k) => k + 1)
|
||||
} else if (current < size - 2) {
|
||||
arr = Array.from(function* gen(i, l) { while (i < l) yield i++; }(1, size - 2 + 1))
|
||||
arr.push('...')
|
||||
arr.push(total)
|
||||
} else if (total - current < size - 2) {
|
||||
arr.push(1)
|
||||
arr.push('...')
|
||||
arr = arr.concat(Array.from(function* gen(i, l) { while (i < l) yield i++; }(total - size + 2, total + 1)))
|
||||
} else {
|
||||
arr.push(1)
|
||||
arr.push('...')
|
||||
arr = arr.concat(Array.from(function* gen(i, l) { while (i < l) yield i++; }(current - Math.floor((size - 4) / 2), current - Math.floor((size - 4) / 2) + size - 4 + 1)))
|
||||
arr.push('...')
|
||||
arr.push(total)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
const pageArrayLg = computed(() => {
|
||||
const current = props.modelValue
|
||||
const total = props.pageTotal
|
||||
return genPageArray(current, total, 17)
|
||||
})
|
||||
const pageArrayMd = computed(() => {
|
||||
const current = props.modelValue
|
||||
const total = props.pageTotal
|
||||
return genPageArray(current, total, 10)
|
||||
})
|
||||
const pageArraySm = computed(() => {
|
||||
const current = props.modelValue
|
||||
const total = props.pageTotal
|
||||
return genPageArray(current, total, 6)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="container" v-if="props.pageTotal > 1">
|
||||
<div class="paper-item" @click="onPrev" style="display: flex;"><</div>
|
||||
<div v-for="(item, index) in pageArrayLg" :key="index" @click="setPageNum(item)" class="paper-item paper-lg"
|
||||
:class="{ 'active': item == props.modelValue }">{{ item }}</div>
|
||||
<div v-for="(item, index) in pageArrayMd" :key="index" @click="setPageNum(item)" class="paper-item paper-md"
|
||||
:class="{ 'active': item == props.modelValue }">{{ item }}</div>
|
||||
<div v-for="(item, index) in pageArraySm" :key="index" @click="setPageNum(item)" class="paper-item paper-sm"
|
||||
:class="{ 'active': item == props.modelValue }">{{ item }}</div>
|
||||
<div class="paper-item" @click="onNext" style="display: flex;">></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
margin: 1rem 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
/* font-weight: 600; */
|
||||
}
|
||||
|
||||
@media screen and (min-width: 780px) {
|
||||
|
||||
.paper-lg,
|
||||
.paper-sm {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.paper-md {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1024px) {
|
||||
|
||||
.paper-md,
|
||||
.paper-sm {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.paper-lg {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 780px) {
|
||||
|
||||
.paper-lg,
|
||||
.paper-md {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.paper-sm {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.paper-item {
|
||||
height: 2rem;
|
||||
width: 2rem;
|
||||
margin: 0 .5rem;
|
||||
padding: 0rem .25rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #f6f6f7;
|
||||
border-radius: .25rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.paper-item:hover {
|
||||
background-color: #0099ff0d;
|
||||
--un-text-opacity: 1;
|
||||
color: #0099ff;
|
||||
}
|
||||
|
||||
.paper-item.active {
|
||||
background-color: #0099ff0d;
|
||||
--un-text-opacity: 1;
|
||||
color: #0099ff;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
.paper-item {
|
||||
background-color: #9ca3af0d;
|
||||
}
|
||||
}</style>
|
||||
Reference in New Issue
Block a user