From 9de15b4536c7b01b3e59e5f9568a9aa91f0a1ef6 Mon Sep 17 00:00:00 2001
From: gimmyhehe <975402925@qq.com>
Date: Fri, 29 Dec 2023 10:01:52 +0800
Subject: [PATCH] refactor(pager): [pager] pager component refactor (#1198)
* refactor(pager): [pager] pager component refactor
* refactor(pager): [pager] pager component refactor
* refactor(pager): [pager] pager component refactor
* refactor(pager): [pager] pager component refactor
---
.../before-page-change-composition-api.vue | 2 +-
.../demos/pc/app/pager/before-page-change.vue | 2 +-
.../pager/custom-layout-composition-api.vue | 14 +-
.../demos/pc/app/pager/custom-layout.vue | 14 +-
.../pager/custom-total-composition-api.vue | 38 +-
.../sites/demos/pc/app/pager/custom-total.vue | 38 +-
.../hide-on-single-page-composition-api.vue | 2 +-
.../pc/app/pager/hide-on-single-page.spec.ts | 2 +-
.../pc/app/pager/hide-on-single-page.vue | 2 +-
.../app/pager/pager-event-composition-api.vue | 15 +-
.../sites/demos/pc/app/pager/pager-event.vue | 15 +-
.../sites/demos/pc/app/pager/webdoc/pager.js | 6 +-
packages/renderless/src/pager/index.ts | 453 +++++++++
packages/renderless/src/pager/vue.ts | 134 ++-
packages/renderless/types/pager.type.ts | 96 ++
packages/vue/src/pager/src/index.ts | 127 +--
packages/vue/src/pager/src/pc.vue | 901 ++++--------------
17 files changed, 999 insertions(+), 862 deletions(-)
create mode 100644 packages/renderless/src/pager/index.ts
diff --git a/examples/sites/demos/pc/app/pager/before-page-change-composition-api.vue b/examples/sites/demos/pc/app/pager/before-page-change-composition-api.vue
index 334f0939d..e071f7479 100644
--- a/examples/sites/demos/pc/app/pager/before-page-change-composition-api.vue
+++ b/examples/sites/demos/pc/app/pager/before-page-change-composition-api.vue
@@ -18,7 +18,7 @@ const currentPage = ref(5)
function onBeforePageChange(param) {
const { callback, rollback } = param
- Modal.confirm('您确定要放弃当前页的修改吗?').then((res) => {
+ Modal.confirm('您确定要继续变更操作吗?').then((res) => {
if (res === 'confirm') {
callback && callback()
} else {
diff --git a/examples/sites/demos/pc/app/pager/before-page-change.vue b/examples/sites/demos/pc/app/pager/before-page-change.vue
index aa27a4db9..cd8cda24c 100644
--- a/examples/sites/demos/pc/app/pager/before-page-change.vue
+++ b/examples/sites/demos/pc/app/pager/before-page-change.vue
@@ -25,7 +25,7 @@ export default {
methods: {
onBeforePageChange(param) {
const { callback, rollback } = param
- Modal.confirm('您确定要放弃当前页的修改吗?').then((res) => {
+ Modal.confirm('您确定要继续变更操作吗?').then((res) => {
if (res === 'confirm') {
callback && callback()
} else {
diff --git a/examples/sites/demos/pc/app/pager/custom-layout-composition-api.vue b/examples/sites/demos/pc/app/pager/custom-layout-composition-api.vue
index 56589000f..3fb5ceb79 100644
--- a/examples/sites/demos/pc/app/pager/custom-layout-composition-api.vue
+++ b/examples/sites/demos/pc/app/pager/custom-layout-composition-api.vue
@@ -1,10 +1,12 @@
-
-
- 默认插槽
-
-
-
+
+
+
+ 默认插槽
+
+
+
+
diff --git a/examples/sites/demos/pc/app/pager/pager-event.vue b/examples/sites/demos/pc/app/pager/pager-event.vue
index 54d23e226..3800b50f8 100644
--- a/examples/sites/demos/pc/app/pager/pager-event.vue
+++ b/examples/sites/demos/pc/app/pager/pager-event.vue
@@ -34,27 +34,32 @@ export default {
methods: {
handleCurrentChange(val) {
Modal.message({
- message: `current-change 事件,当前页: ${val}`
+ message: `current-change 事件,当前页: ${val}`,
+ status: 'info'
})
},
handleSizeChange(val) {
Modal.message({
- message: `size-change 事件,每页条目数: ${val}`
+ message: `size-change 事件,每页条目数: ${val}`,
+ status: 'info'
})
},
prevClick(val) {
Modal.message({
- message: `prev-click 事件,当前页: ${val}`
+ message: `prev-click 事件,当前页: ${val}`,
+ status: 'info'
})
},
nextClick(val) {
Modal.message({
- message: `next-click 事件,当前页: ${val}`
+ message: `next-click 事件,当前页: ${val}`,
+ status: 'info'
})
},
fetchData: debounce(() => {
Modal.message({
- message: '模拟后台拉取数据'
+ message: '模拟后台拉取数据',
+ status: 'info'
})
})
}
diff --git a/examples/sites/demos/pc/app/pager/webdoc/pager.js b/examples/sites/demos/pc/app/pager/webdoc/pager.js
index 0f18c2677..bf0ff3e9f 100644
--- a/examples/sites/demos/pc/app/pager/webdoc/pager.js
+++ b/examples/sites/demos/pc/app/pager/webdoc/pager.js
@@ -131,9 +131,9 @@ export default {
},
{
'demoId': 'hide-on-single-page',
- 'name': { 'zh-CN': '只有一页时隐藏分页', 'en-US': 'Grid Table Pagination' },
+ 'name': { 'zh-CN': '单页时隐藏', 'en-US': 'Grid Table Pagination' },
'desc': {
- 'zh-CN': '
当 hide-on-single-page
为 true
时,只有一页时会隐藏分页。
\n',
+ 'zh-CN': '通过 hide-on-single-page
设置当仅有一页时是否隐藏分页组件。
\n',
'en-US': 'When there is only one page, the pagination will be hidden.
\n'
},
'codeFiles': ['hide-on-single-page.vue']
@@ -164,7 +164,7 @@ export default {
'name': { 'zh-CN': '分页变更前置处理', 'en-US': 'Pre processing of pagination changes' },
'desc': {
'zh-CN':
- '通过 is-before-page-change
开启前置处理特性,翻页或者改变页大小时会触发 before-page-change
事件。事件函数类型为 IBeforeChangeEvent ,调用传参中的 callback
继续变更,调用 rollback
中止变更。
\n',
+ '通过 is-before-page-change
开启前置处理特性,翻页或者改变页大小时会触发 before-page-change
事件。调用传参中的 callback
继续变更,调用 rollback
中止变更。
\n',
'en-US':
'By enabling the pre processing feature through is before page change
, the before page change
event is triggered when flipping or changing page size. The event function type is IBeforeChangeEvent , call callback
in the passed parameters to continue the change, and call rollback
to abort the change.
\n'
},
diff --git a/packages/renderless/src/pager/index.ts b/packages/renderless/src/pager/index.ts
new file mode 100644
index 000000000..268cdc154
--- /dev/null
+++ b/packages/renderless/src/pager/index.ts
@@ -0,0 +1,453 @@
+import type { IPagerRenderlessParams } from '@/types'
+import { emitEvent } from '../common/event'
+
+export const computedShowPager =
+ ({ props, state }: Pick) =>
+ (): boolean => {
+ const hidePager = props.hideOnSinglePage && (!state.internalPageCount || state.internalPageCount === 1)
+ return state.internalLayout.length > 0 && !hidePager
+ }
+
+export const computedInternalLayout =
+ ({ props }: Pick) =>
+ (): string[] => {
+ let layout = ''
+
+ if (props.mode && !props.layout) {
+ props.mode === 'number' && (layout = 'total, sizes, prev, pager, next, jumper')
+ props.mode === 'simple' && (layout = 'sizes, total, prev, current, next')
+ props.mode === 'complete' && (layout = 'sizes, total, prev, pager, next, jumper')
+ props.mode === 'fixed' && (layout = 'prev,pager,next')
+ } else if ((!props.mode && props.layout) || (props.mode && props.layout)) {
+ layout = props.layout
+ } else {
+ layout = 'total, prev, pager, next, jumper'
+ }
+
+ if (!layout) {
+ return []
+ } else {
+ const components = layout.split(',').map((item) => item.trim())
+ return components
+ }
+ }
+
+export const computedTotalText =
+ ({ props, t }: Pick) =>
+ (): string => {
+ if (typeof props.customTotal === 'string') return props.customTotal
+
+ const totals = Number(props.total)
+
+ if (isNaN(totals)) return '0'
+
+ const HUNDRED_THOUSAND = 100000
+ const MILLION = 1000000
+ const TEN_MILLION = 10000000
+ if (totals <= HUNDRED_THOUSAND) {
+ return String(totals)
+ } else if (totals <= MILLION) {
+ return t('ui.page.hundredThousand')
+ } else if (totals <= TEN_MILLION) {
+ return t('ui.page.million')
+ } else {
+ return t('ui.page.tenMillion')
+ }
+ }
+
+export const computedInternalPageCount =
+ ({ props, state }: Pick) =>
+ (): number | null => {
+ if (typeof props.total === 'number') {
+ return Math.max(1, Math.ceil(props.total / state.internalPageSize))
+ } else if (typeof props.pageCount === 'number') {
+ return Math.max(1, props.pageCount)
+ }
+
+ return null
+ }
+
+export const handleJumperFocus =
+ ({ state }: Pick) =>
+ (e: Event): void => {
+ state.jumperBackup = (e.target as HTMLInputElement)?.value
+ }
+
+export const watchInternalCurrentPage =
+ ({ state, emit }: Pick) =>
+ (currentPage: number): void => {
+ const value = String(currentPage)
+
+ if (state.jumperValue !== value) {
+ state.jumperValue = value
+ }
+ emit('update:currentPage', currentPage)
+ emit('current-change', currentPage)
+ state.lastEmittedPage = -1
+ }
+
+export const watchPageSizes =
+ ({ state, props }: Pick) =>
+ (newVal: number[]): void => {
+ if (Array.isArray(newVal)) {
+ state.internalPageSize = newVal.includes(props.pageSize) ? props.pageSize : newVal[0]
+ }
+ }
+
+export const watchCurrentPage =
+ ({ state, api }: Pick) =>
+ (curPage: number): void => {
+ state.internalCurrentPage = api.getValidCurrentPage(curPage)
+ }
+
+export const watchInternalPageCount =
+ ({ state, api }: Pick) =>
+ (pageCount: number | null): void => {
+ const oldCurPage = state.internalCurrentPage
+
+ if (pageCount && pageCount > 0 && oldCurPage === 0) {
+ state.internalCurrentPage = 1
+ } else if (oldCurPage > Number(pageCount)) {
+ state.internalCurrentPage = pageCount || 1
+ state.userChangePageSize && api.emitChange()
+ }
+
+ state.userChangePageSize = false
+ }
+
+export const watchPageSize =
+ ({ state }: Pick) =>
+ (pageSize: number): void => {
+ state.internalPageSize = isNaN(pageSize) ? 10 : pageSize
+ }
+
+export const watchTotal =
+ ({ state }: Pick) =>
+ (total: number | undefined): void => {
+ state.internalTotal = total
+ }
+
+export const handleSizeChange =
+ ({ props, state, api, emit, vm }: Pick) =>
+ (val: number): void => {
+ // 防止用户pagerSizes传入字符串数组导致bug
+ val = Number(val)
+ if (val !== state.internalPageSize) {
+ const callback = () => {
+ if (!api.beforeChangeHandler()) {
+ return
+ }
+
+ state.internalPageSize = val
+ state.userChangePageSize = true
+ state.showSizes = false
+ emit('update:pageSize', val)
+ emit('size-change', val)
+ emit('page-change', {
+ currentPage: state.internalCurrentPage,
+ pageSize: val,
+ total: state.internalTotal
+ })
+ vm.$refs.sizesList[0].state.showPopper = false
+ }
+
+ if (props.isBeforePageChange) {
+ let newPageSize = val
+ let currentPageSize = state.internalPageSize
+ let params = { newPageSize, currentPageSize, callback }
+
+ api.beforeSizeChangeHandler(params)
+ } else {
+ callback()
+ }
+ }
+ }
+
+export const handleJumperInput =
+ ({ state }: Pick) =>
+ (e: Event): void => {
+ const target = e.target as HTMLInputElement
+ if (!target.value) {
+ state.jumperValue = ''
+ } else if (/^\d+$/.test(target.value)) {
+ state.jumperValue = target.value || '1'
+ }
+ target.value = state.jumperValue
+ }
+
+export const handleJumperChange =
+ ({ props, state, api }: Pick) =>
+ (): void => {
+ api.parseValueNumber()
+
+ const callback = () => {
+ api.handleJumperClick()
+ }
+ const rollback = () => {
+ state.jumperValue = String(state.jumperBackup)
+ }
+ const newPage = state.jumperValue
+ const currentPage = state.jumperBackup
+
+ if (props.isBeforePageChange && newPage !== currentPage) {
+ const params = { newPage, currentPage, callback, rollback }
+
+ api.beforePagerChangeHandler(params)
+ } else {
+ callback()
+ }
+ }
+
+export const handleJumperClick =
+ ({ props, state, api }: Pick) =>
+ (): void => {
+ if (!api.canJumperGo() || props.disabled) return
+
+ state.internalCurrentPage = api.getValidCurrentPage(state.jumperValue)
+ api.emitChange()
+ }
+
+export const isValueNumber =
+ ({ state }: Pick) =>
+ (): boolean => {
+ return !isNaN(Number(state.jumperValue))
+ }
+
+export const parseValueNumber =
+ ({ state }: Pick) =>
+ (): void => {
+ let value = Number(
+ String(state.jumperValue)
+ .split(/[^0-9-+.]/)
+ .join('')
+ )
+
+ if (isNaN(value)) {
+ value = 1
+ }
+
+ value = Number(value.toFixed(0))
+
+ const min = 1
+ const max = state.internalPageCount || 1
+
+ if (value >= max) {
+ state.jumperValue = String(max)
+ } else if (value <= min) {
+ state.jumperValue = String(min)
+ } else {
+ state.jumperValue = String(value)
+ }
+ }
+
+export const handleSizeShowPopover =
+ ({ state, props }: Pick) =>
+ (): void => {
+ if (props.disabled) {
+ state.showSizes = false
+ return
+ }
+ state.showSizes = true
+ }
+
+export const handleSizeHidePopover =
+ ({ state }: Pick) =>
+ (): void => {
+ state.showSizes = false
+ }
+
+export const canJumperGo =
+ ({ props, state, vm }: Pick) =>
+ (): boolean => {
+ const inputValue = Number(vm.$refs.jumperInput[0].value || 0)
+ const currentPage = Number(state.internalCurrentPage || 0)
+ return props.accurateJumper ? inputValue !== currentPage : true
+ }
+export const beforeSizeChangeHandler =
+ ({ state, emit }: Pick) =>
+ (params): void => {
+ const { newPageSize, currentPageSize, callback } = params
+ const newPage = 1
+ const currentPage = state.internalCurrentPage
+ const temp = {
+ newPage,
+ newPageSize,
+ currentPage,
+ currentPageSize,
+ callback
+ }
+
+ emit('before-page-change', temp)
+ }
+
+export const beforePagerChangeHandler =
+ ({ state, emit }: Pick) =>
+ (params): void => {
+ const { newPage, currentPage, callback, rollback } = params
+ const newPageSize = state.internalPageSize
+ const currentPageSize = state.internalPageSize
+ const temp = {
+ newPage,
+ newPageSize,
+ currentPage,
+ currentPageSize,
+ callback,
+ rollback
+ }
+
+ emit('before-page-change', temp)
+ }
+
+export const beforeJumperChangeHandler =
+ ({ state, emit }: Pick) =>
+ (params): void => {
+ const { newPage, currentPage, callback, rollback } = params
+ const newPageSize = state.internalPageSize
+ const currentPageSize = state.internalPageSize
+ const temp = {
+ newPage,
+ newPageSize,
+ currentPage,
+ currentPageSize,
+ callback,
+ rollback
+ }
+
+ emit('before-page-change', temp)
+ }
+
+export const copyEmit =
+ ({ emit }: Pick) =>
+ (...args): void => {
+ emit(args[0], ...args.slice(1))
+ }
+
+export const beforeChangeHandler =
+ ({ state, api }: Pick) =>
+ (val: number = -1) => {
+ return emitEvent(api.copyEmit, 'before-change', state.internalCurrentPage, this, val)
+ }
+export const handleCurrentChange =
+ ({ state, api }: Pick) =>
+ (val: number): void => {
+ if (!api.beforeChangeHandler(val)) {
+ return
+ }
+
+ state.internalCurrentPage = api.getValidCurrentPage(val)
+ state.userChangePageSize = true
+ api.emitChange()
+ }
+
+export const prev =
+ ({ state, props, api, emit }: Pick) =>
+ (): void => {
+ const callback = () => {
+ if (props.disabled || !api.beforeChangeHandler(state.internalCurrentPage - 1)) {
+ return
+ }
+
+ const newVal = state.internalCurrentPage - 1
+
+ state.internalCurrentPage = api.getValidCurrentPage(newVal)
+ emit('prev-click', state.internalCurrentPage)
+ api.emitChange()
+ }
+
+ if (props.isBeforePageChange) {
+ const newPage = state.internalCurrentPage - 1
+ const temp = api.buildBeforePageChangeParam({ newPage, callback })
+
+ emit('before-page-change', temp)
+ } else {
+ callback()
+ }
+ }
+
+export const next =
+ ({ props, state, api, emit }: Pick) =>
+ (): void => {
+ const callback = () => {
+ if (props.disabled || !api.beforeChangeHandler(state.internalCurrentPage + 1)) {
+ return
+ }
+
+ const newVal = state.internalCurrentPage + 1
+
+ state.internalCurrentPage = api.getValidCurrentPage(newVal)
+ emit('next-click', state.internalCurrentPage)
+ api.emitChange()
+ }
+
+ if (props.isBeforePageChange) {
+ const newPage = state.internalCurrentPage + 1
+ const temp = api.buildBeforePageChangeParam({ newPage, callback })
+
+ emit('before-page-change', temp)
+ } else {
+ callback()
+ }
+ }
+
+export const buildBeforePageChangeParam =
+ ({ state }: Pick) =>
+ (param) => {
+ const currentPage = state.internalCurrentPage
+ const newPageSize = state.internalPageSize
+ const currentPageSize = state.internalPageSize
+
+ return { currentPage, newPageSize, currentPageSize, ...param }
+ }
+
+export const getValidCurrentPage =
+ ({ state }: Pick) =>
+ (val: string | number) => {
+ const parseVal = Number(val)
+
+ const hasPageCount = typeof state.internalPageCount === 'number'
+
+ let resetVal
+
+ if (hasPageCount) {
+ if (parseVal < 1) {
+ resetVal = 1
+ } else if (parseVal > (state.internalPageCount || 0)) {
+ resetVal = state.internalPageCount
+ }
+ } else {
+ if (isNaN(parseVal) || parseVal < 1) {
+ resetVal = 1
+ }
+ }
+
+ if (resetVal === undefined && isNaN(parseVal)) {
+ resetVal = 1
+ } else if (resetVal === 0) {
+ resetVal = 1
+ }
+
+ return resetVal === undefined ? parseVal : resetVal
+ }
+
+export const emitChange =
+ ({ state, nextTick, emit }: Pick) =>
+ (): void => {
+ nextTick(() => {
+ if (state.internalCurrentPage !== state.lastEmittedPage || state.userChangePageSize) {
+ emit('update:current-page', state.internalCurrentPage)
+ emit('page-change', {
+ currentPage: state.internalCurrentPage,
+ pageSize: state.internalPageSize,
+ total: state.internalTotal
+ })
+ state.lastEmittedPage = state.internalCurrentPage
+ state.userChangePageSize = false
+ }
+ })
+ }
+
+export const setTotal =
+ ({ state }: Pick) =>
+ (val: number): void => {
+ state.internalTotal = val
+ }
diff --git a/packages/renderless/src/pager/vue.ts b/packages/renderless/src/pager/vue.ts
index abec40efa..57a41facf 100644
--- a/packages/renderless/src/pager/vue.ts
+++ b/packages/renderless/src/pager/vue.ts
@@ -1,7 +1,135 @@
-export const api = []
+import type {
+ IPagerApi,
+ IPagerProps,
+ IPagerState,
+ ISharedRenderlessParamHooks,
+ IPagerRenderlessParamUtils
+} from '@/types'
+import {
+ computedShowPager,
+ computedInternalLayout,
+ computedTotalText,
+ computedInternalPageCount,
+ handleJumperFocus,
+ handleSizeChange,
+ handleJumperInput,
+ handleJumperChange,
+ handleJumperClick,
+ isValueNumber,
+ parseValueNumber,
+ handleSizeShowPopover,
+ handleSizeHidePopover,
+ canJumperGo,
+ beforeSizeChangeHandler,
+ beforePagerChangeHandler,
+ copyEmit,
+ beforeChangeHandler,
+ handleCurrentChange,
+ prev,
+ next,
+ buildBeforePageChangeParam,
+ getValidCurrentPage,
+ emitChange,
+ setTotal,
+ watchInternalCurrentPage,
+ watchPageSizes,
+ watchCurrentPage,
+ watchInternalPageCount,
+ watchPageSize,
+ watchTotal
+} from './index'
-export const renderless = () => {
- const api = {}
+export const api = [
+ 'state',
+ 'handleJumperFocus',
+ 'handleSizeChange',
+ 'handleJumperInput',
+ 'handleJumperChange',
+ 'handleJumperClick',
+ 'isValueNumber',
+ 'parseValueNumber',
+ 'handleSizeShowPopover',
+ 'handleSizeHidePopover',
+ 'canJumperGo',
+ 'beforeSizeChangeHandler',
+ 'beforePagerChangeHandler',
+ 'beforeJumperChangeHandler',
+ 'beforeChangeHandler',
+ 'handleCurrentChange',
+ 'prev',
+ 'next',
+ 'buildBeforePageChangeParam',
+ 'getValidCurrentPage',
+ 'emitChange',
+ 'setTotal'
+]
+
+export const renderless = (
+ props: IPagerProps,
+ { reactive, computed, watch }: ISharedRenderlessParamHooks,
+ { emit, vm, nextTick, t }: IPagerRenderlessParamUtils
+): IPagerApi => {
+ const api = {} as IPagerApi
+
+ const state: IPagerState = reactive({
+ showSizes: false,
+ internalCurrentPage: 1,
+ internalPageSize: props.pageSize,
+ lastEmittedPage: -1,
+ userChangePageSize: false,
+ internalTotal: props.total,
+ jumperValue: '1',
+ jumperBackup: '1',
+ showPager: computed(() => api.computedShowPager()),
+ internalLayout: computed(() => api.computedInternalLayout()),
+ totalText: computed(() => api.computedTotalText()),
+ internalPageCount: computed(() => api.computedInternalPageCount())
+ })
+
+ Object.assign(api, {
+ state,
+ computedShowPager: computedShowPager({ props, state }),
+ computedInternalLayout: computedInternalLayout({ props }),
+ computedTotalText: computedTotalText({ props, t }),
+ computedInternalPageCount: computedInternalPageCount({ props, state }),
+ getValidCurrentPage: getValidCurrentPage({ state }),
+ handleJumperFocus: handleJumperFocus({ state }),
+ handleSizeChange: handleSizeChange({ props, state, api, emit, vm }),
+ handleJumperInput: handleJumperInput({ state }),
+ handleJumperChange: handleJumperChange({ props, state, api }),
+ handleJumperClick: handleJumperClick({ props, state, api }),
+ isValueNumber: isValueNumber({ state }),
+ parseValueNumber: parseValueNumber({ state }),
+ handleSizeShowPopover: handleSizeShowPopover({ state, props }),
+ handleSizeHidePopover: handleSizeHidePopover({ state }),
+ canJumperGo: canJumperGo({ props, state, vm }),
+ beforeSizeChangeHandler: beforeSizeChangeHandler({ state, emit }),
+ beforePagerChangeHandler: beforePagerChangeHandler({ state, emit }),
+ copyEmit: copyEmit({ emit }),
+ beforeChangeHandler: beforeChangeHandler({ state, api }),
+ handleCurrentChange: handleCurrentChange({ state, api }),
+ prev: prev({ state, props, api, emit }),
+ next: next({ props, state, api, emit }),
+ buildBeforePageChangeParam: buildBeforePageChangeParam({ state }),
+ emitChange: emitChange({ state, nextTick, emit }),
+ setTotal: setTotal({ state }),
+ // watch
+ watchInternalCurrentPage: watchInternalCurrentPage({ state, emit }),
+ watchPageSizes: watchPageSizes({ state, props }),
+ watchCurrentPage: watchCurrentPage({ state, api }),
+ watchInternalPageCount: watchInternalPageCount({ state, api }),
+ watchPageSize: watchPageSize({ state }),
+ watchTotal: watchTotal({ state })
+ })
+
+ state.internalCurrentPage = api.getValidCurrentPage(props.currentPage)
+
+ watch(() => state.internalCurrentPage, api.watchInternalCurrentPage)
+ watch(() => props.pageSizes, api.watchPageSizes, { immediate: true })
+ watch(() => props.currentPage, api.watchCurrentPage)
+ watch(() => state.internalPageCount, api.watchInternalPageCount)
+ watch(() => props.pageSize, api.watchPageSize, { immediate: true })
+ watch(() => props.total, api.watchTotal)
return api
}
diff --git a/packages/renderless/types/pager.type.ts b/packages/renderless/types/pager.type.ts
index e69de29bb..61d9999b1 100644
--- a/packages/renderless/types/pager.type.ts
+++ b/packages/renderless/types/pager.type.ts
@@ -0,0 +1,96 @@
+import type { ExtractPropTypes } from 'vue'
+import type { pagerProps } from '@/pager/src'
+import type { ISharedRenderlessFunctionParams, ISharedRenderlessParamUtils } from './shared.type'
+import type {
+ computedShowPager,
+ computedInternalLayout,
+ computedTotalText,
+ computedInternalPageCount,
+ handleJumperFocus,
+ handleSizeChange,
+ handleJumperInput,
+ handleJumperChange,
+ handleJumperClick,
+ isValueNumber,
+ parseValueNumber,
+ handleSizeShowPopover,
+ handleSizeHidePopover,
+ canJumperGo,
+ beforeSizeChangeHandler,
+ beforePagerChangeHandler,
+ copyEmit,
+ beforeChangeHandler,
+ handleCurrentChange,
+ prev,
+ next,
+ buildBeforePageChangeParam,
+ getValidCurrentPage,
+ emitChange,
+ setTotal,
+ watchInternalCurrentPage,
+ watchPageSizes,
+ watchCurrentPage,
+ watchInternalPageCount,
+ watchPageSize,
+ watchTotal
+} from '../src/pager'
+
+export type IPagerProps = ExtractPropTypes
+
+export interface IPagerState {
+ showPager: boolean
+ showSizes: boolean
+ internalCurrentPage: number
+ internalPageSize: number
+ lastEmittedPage: number
+ userChangePageSize: boolean
+ internalTotal: number | undefined
+ jumperValue: string
+ jumperBackup: string
+ internalLayout: string[]
+ totalText: string
+ internalPageCount: number | null
+}
+
+export interface IPagerApi {
+ state: IPagerState
+ t: IPagerRenderlessParamUtils['t']
+ computedShowPager: ReturnType
+ computedInternalLayout: ReturnType
+ computedTotalText: ReturnType
+ computedInternalPageCount: ReturnType
+ handleJumperFocus: ReturnType
+ handleSizeChange: ReturnType
+ handleJumperInput: ReturnType
+ handleJumperChange: ReturnType
+ handleJumperClick: ReturnType
+ isValueNumber: ReturnType
+ parseValueNumber: ReturnType
+ handleSizeShowPopover: ReturnType
+ handleSizeHidePopover: ReturnType
+ canJumperGo: ReturnType
+ beforeSizeChangeHandler: ReturnType
+ beforePagerChangeHandler: ReturnType
+ copyEmit: ReturnType
+ beforeChangeHandler: ReturnType
+ handleCurrentChange: ReturnType
+ prev: ReturnType
+ next: ReturnType
+ buildBeforePageChangeParam: ReturnType
+ getValidCurrentPage: ReturnType
+ emitChange: ReturnType
+ setTotal: ReturnType
+ watchInternalCurrentPage: ReturnType
+ watchPageSizes: ReturnType
+ watchCurrentPage: ReturnType
+ watchInternalPageCount: ReturnType
+ watchPageSize: ReturnType
+ watchTotal: ReturnType
+}
+export type IPagerRenderlessParams = ISharedRenderlessFunctionParams & {
+ api: IPagerApi
+ state: IPagerState
+ props: IPagerProps
+}
+
+export type IPagerRenderlessParamUtils = ISharedRenderlessParamUtils
diff --git a/packages/vue/src/pager/src/index.ts b/packages/vue/src/pager/src/index.ts
index 85354362f..8f8e63a48 100644
--- a/packages/vue/src/pager/src/index.ts
+++ b/packages/vue/src/pager/src/index.ts
@@ -1,70 +1,73 @@
+import type { PropType } from 'vue'
import { $props, $prefix, $setup, defineComponent } from '@opentiny/vue-common'
import template from 'virtual-template?pc|mobile-first'
+export const pagerProps = {
+ ...$props,
+ accurateJumper: {
+ type: Boolean,
+ default: () => true
+ },
+ appendToBody: {
+ type: Boolean,
+ default: () => true
+ },
+ currentPage: {
+ type: Number,
+ default: () => 1
+ },
+ disabled: {
+ type: Boolean,
+ default: () => false
+ },
+ hideOnSinglePage: Boolean,
+ isBeforePageChange: Boolean,
+ layout: String,
+ mode: String,
+ nextText: String,
+ pageCount: Number,
+ pageSize: {
+ type: Number,
+ default: () => 10
+ },
+ pageSizes: {
+ type: Array as PropType,
+ default: () => [10, 20, 30, 40, 50, 100]
+ },
+ pagerCount: {
+ type: Number,
+ validator: (value) => (value | 0) === value && value > 2 && value < 22 && value % 2 === 1,
+ default: () => 7
+ },
+ popperAppendToBody: {
+ type: Boolean,
+ default: () => true
+ },
+ showTotalLoading: {
+ type: Boolean,
+ default: () => false
+ },
+ customTotal: {
+ type: [Boolean, String],
+ default: () => false
+ },
+ popperClass: String,
+ prevText: String,
+ total: Number,
+ size: {
+ type: String,
+ default: ''
+ },
+ align: {
+ // 分页对齐方式 【left,center,right】
+ type: String,
+ validator: (value) => ['left', 'center', 'right'].includes(value)
+ }
+}
+
export default defineComponent({
name: $prefix + 'Pager',
- props: {
- ...$props,
- accurateJumper: {
- type: Boolean,
- default: () => true
- },
- appendToBody: {
- type: Boolean,
- default: () => true
- },
- currentPage: {
- type: Number,
- default: () => 1
- },
- disabled: {
- type: Boolean,
- default: () => false
- },
- hideOnSinglePage: Boolean,
- isBeforePageChange: Boolean,
- layout: String,
- mode: String,
- nextText: String,
- pageCount: Number,
- pageSize: {
- type: Number,
- default: () => 10
- },
- pageSizes: {
- type: Array,
- default: () => [10, 20, 30, 40, 50, 100]
- },
- pagerCount: {
- type: Number,
- validator: (value) => (value | 0) === value && value > 2 && value < 22 && value % 2 === 1,
- default: () => 7
- },
- popperAppendToBody: {
- type: Boolean,
- default: () => true
- },
- showTotalLoading: {
- type: Boolean,
- default: () => false
- },
- customTotal: {
- type: [Boolean, String],
- default: () => false
- },
- popperClass: String,
- prevText: String,
- total: Number,
- size: {
- type: String,
- default: ''
- },
- align: {
- // 分页对齐方式 【left,center,right】
- type: String,
- validator: (value) => ['left', 'center', 'right'].includes(value)
- }
- },
+ props: pagerProps,
setup(props, context) {
return $setup({ props, context, template })
}
diff --git a/packages/vue/src/pager/src/pc.vue b/packages/vue/src/pager/src/pc.vue
index ec0868ace..1e347f525 100644
--- a/packages/vue/src/pager/src/pc.vue
+++ b/packages/vue/src/pager/src/pc.vue
@@ -9,752 +9,191 @@
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
-->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+