====== Paginator ======
この実装を Vue3 用に移植してみました。
https://github.com/lokyoung/vuejs-paginate/blob/master/src/components/Paginate.vue
実際にリストに実装しての確認は、まだしていません。。。
===== Code =====
import { onBeforeUpdate, ref, computed } from 'https://cdnjs.cloudflare.com/ajax/libs/vue/3.0.2/vue.esm-browser.js';
const Paginator = {
template: `
ul.paginator a { cursor: pointer; }
`,
props: {
value: { type: Number },
pageCount: { type: Number, required: true },
forcePage: { type: Number },
clickHandler: { type: Function, default: () => {} },
pageRange: { type: Number, default: 3 },
marginPages: { type: Number, default: 1 },
prevText: { type: String, default: '<' },
nextText: { type: String, default: '>' },
breakViewText: { type: String, default: '…' },
containerClass: { type: String, default: 'pagination pagination-sm pull-right' },
pageClass: { type: String },
pageLinkClass: { type: String },
prevClass: { type: String },
prevLinkClass: { type: String },
nextClass: { type: String },
nextLinkClass: { type: String },
breakViewClass: { type: String },
breakViewLinkClass: { type: String },
activeClass: { type: String, default: 'active' },
disabledClass: { type: String, default: 'disabled' },
noLiSurround: { type: Boolean, default: false },
firstLastButton: { type: Boolean, default: true },
firstButtonText: { type: String, default: '<<' },
lastButtonText: { type: String, default: '>>' },
hidePrevNext: { type: Boolean, default: false }
},
setup(props, context) {
const innerValue = ref(1)
const selected = computed({
get: function() {
return props.value || innerValue.value
},
set: function(newValue) {
innerValue.value = newValue
}
})
const pages = computed(function() {
let items = {}
if (props.pageCount <= props.pageRange) {
for (let index = 0; index < props.pageCount; index++) {
let page = {
index: index,
content: index + 1,
selected: index === (selected - 1)
}
items[index] = page
}
} else {
const halfPageRange = Math.floor(props.pageRange / 2)
let setPageItem = index => {
let page = {
index: index,
content: index + 1,
selected: index === (selected - 1)
}
items[index] = page
}
let setBreakView = index => {
let breakView = {
disabled: true,
breakView: true
}
items[index] = breakView
}
// 1st - loop thru low end of margin pages
for (let i = 0; i < props.marginPages; i++) {
setPageItem(i);
}
// 2nd - loop thru selected range
let selectedRangeLow = 0;
if (selected.value - halfPageRange > 0) {
selectedRangeLow = selected.value - 1 - halfPageRange;
}
let selectedRangeHigh = selectedRangeLow + props.pageRange - 1;
if (selectedRangeHigh >= props.pageCount) {
selectedRangeHigh = props.pageCount - 1;
selectedRangeLow = selectedRangeHigh - props.pageRange + 1;
}
for (let i = selectedRangeLow; i <= selectedRangeHigh && i <= props.pageCount - 1; i++) {
setPageItem(i);
}
// Check if there is breakView in the left of selected range
if (selectedRangeLow > props.marginPages) {
setBreakView(selectedRangeLow - 1)
}
// Check if there is breakView in the right of selected range
if (selectedRangeHigh + 1 < props.pageCount - props.marginPages) {
setBreakView(selectedRangeHigh + 1)
}
// 3rd - loop thru high end of margin pages
for (let i = props.pageCount - 1; i >= props.pageCount - props.marginPages; i--) {
setPageItem(i);
}
}
return items
})
onBeforeUpdate(() => {
if (props.forcePage === undefined) return
if (props.forcePage !== selected.value) {
selected.value = props.forcePage
}
})
function handlePageSelected(value) {
if (selected.value === value) return
innerValue.value = value
context.emit('input', value)
props.clickHandler(value)
}
function prevPage() {
if (selected.value <= 1) return
handlePageSelected(selected.value - 1)
}
function nextPage() {
if (selected.value >= props.pageCount) return
handlePageSelected(selected.value + 1)
}
function firstPageSelected() {
return selected.value === 1
}
function lastPageSelected() {
return (selected.value === props.pageCount) || (props.pageCount === 0)
}
function selectFirstPage() {
if (selected.value <= 1) return
handlePageSelected(1)
}
function selectLastPage() {
if (selected.value >= props.pageCount) return
handlePageSelected(props.pageCount)
}
return {
innerValue,
selected,
pages,
handlePageSelected,
prevPage,
nextPage,
firstPageSelected,
lastPageSelected,
selectFirstPage,
selectLastPage
}
}
};
export default Paginator;
===== Demo =====