refactor(Pagination): refactor with composition api

This commit is contained in:
chenjiahan 2020-09-02 16:17:06 +08:00
parent 1d7138cde7
commit 1cd9183958

View File

@ -1,5 +1,6 @@
import { createNamespace } from '../utils'; import { createNamespace } from '../utils';
import { BORDER } from '../utils/constant'; import { BORDER } from '../utils/constant';
import { computed, watch } from 'vue';
const [createComponent, bem, t] = createNamespace('pagination'); const [createComponent, bem, t] = createNamespace('pagination');
@ -40,19 +41,20 @@ export default createComponent({
emits: ['change', 'update:modelValue'], emits: ['change', 'update:modelValue'],
computed: { setup(props, { emit, slots }) {
count() { const count = computed(() => {
const count = const { pageCount, totalItems, itemsPerPage } = props;
this.pageCount || Math.ceil(this.totalItems / this.itemsPerPage); const count = pageCount || Math.ceil(totalItems / itemsPerPage);
return Math.max(1, count); return Math.max(1, count);
}, });
pages() { const pages = computed(() => {
const pages = []; const pages = [];
const pageCount = this.count; const pageCount = count.value;
const showPageSize = +this.showPageSize; const showPageSize = +props.showPageSize;
const { modelValue, forceEllipses } = props;
if (this.mode !== 'multi') { if (props.mode !== 'multi') {
return pages; return pages;
} }
@ -64,7 +66,7 @@ export default createComponent({
// recompute if showPageSize // recompute if showPageSize
if (isMaxSized) { if (isMaxSized) {
// Current page is displayed in the middle of the visible ones // Current page is displayed in the middle of the visible ones
startPage = Math.max(this.modelValue - Math.floor(showPageSize / 2), 1); startPage = Math.max(modelValue - Math.floor(showPageSize / 2), 1);
endPage = startPage + showPageSize - 1; endPage = startPage + showPageSize - 1;
// Adjust if limit is exceeded // Adjust if limit is exceeded
@ -76,91 +78,97 @@ export default createComponent({
// Add page number links // Add page number links
for (let number = startPage; number <= endPage; number++) { for (let number = startPage; number <= endPage; number++) {
const page = makePage(number, number, number === this.modelValue); const page = makePage(number, number, number === modelValue);
pages.push(page); pages.push(page);
} }
// Add links to move between page sets // Add links to move between page sets
if (isMaxSized && showPageSize > 0 && this.forceEllipses) { if (isMaxSized && showPageSize > 0 && forceEllipses) {
if (startPage > 1) { if (startPage > 1) {
const previousPageSet = makePage(startPage - 1, '...', false); const prevPages = makePage(startPage - 1, '...');
pages.unshift(previousPageSet); pages.unshift(prevPages);
} }
if (endPage < pageCount) { if (endPage < pageCount) {
const nextPageSet = makePage(endPage + 1, '...', false); const nextPages = makePage(endPage + 1, '...');
pages.push(nextPageSet); pages.push(nextPages);
} }
} }
return pages; return pages;
}, });
},
watch: { const select = (page, emitChange) => {
modelValue: { page = Math.min(count.value, Math.max(1, page));
handler(page) {
this.select(page);
},
immediate: true,
},
},
methods: { if (props.modelValue !== page) {
select(page, emitChange) { emit('update:modelValue', page);
page = Math.min(this.count, Math.max(1, page));
if (this.modelValue !== page) {
this.$emit('update:modelValue', page);
if (emitChange) { if (emitChange) {
this.$emit('change', page); emit('change', page);
} }
} }
},
},
render() {
const value = this.modelValue;
const simple = this.mode !== 'multi';
const onSelect = (value) => () => {
this.select(value, true);
}; };
return ( watch(() => props.modelValue, select, { immediate: true });
<ul class={bem({ simple })}>
<li const renderDesc = () => {
class={[bem('item', { disabled: value === 1 }), bem('prev'), BORDER]} if (props.mode !== 'multi') {
onClick={onSelect(value - 1)} return (
>
{this.prevText || t('prev')}
</li>
{this.pages.map((page) => (
<li
class={[bem('item', { active: page.active }), bem('page'), BORDER]}
onClick={onSelect(page.number)}
>
{page.text}
</li>
))}
{simple && (
<li class={bem('page-desc')}> <li class={bem('page-desc')}>
{this.$slots.pageDesc {slots.pageDesc
? this.$slots.pageDesc() ? slots.pageDesc()
: `${value}/${this.count}`} : `${props.modelValue}/${count.value}`}
</li> </li>
)} );
<li }
class={[ };
bem('item', { disabled: value === this.count }),
bem('next'), return () => {
BORDER, const value = props.modelValue;
]} const simple = props.mode !== 'multi';
onClick={onSelect(value + 1)}
> const onSelect = (value) => () => {
{this.nextText || t('next')} select(value, true);
</li> };
</ul>
); return (
<ul class={bem({ simple })}>
<li
class={[
bem('item', { disabled: value === 1 }),
bem('prev'),
BORDER,
]}
onClick={onSelect(value - 1)}
>
{props.prevText || t('prev')}
</li>
{pages.value.map((page) => (
<li
class={[
bem('item', { active: page.active }),
bem('page'),
BORDER,
]}
onClick={onSelect(page.number)}
>
{page.text}
</li>
))}
{renderDesc()}
<li
class={[
bem('item', { disabled: value === count.value }),
bem('next'),
BORDER,
]}
onClick={onSelect(value + 1)}
>
{props.nextText || t('next')}
</li>
</ul>
);
};
}, },
}); });