Skip to content

Commit 22420fa

Browse files
committed
feat(pager): 优化移动端分页组件,简化模板结构,增强功能和可读性
1 parent 9ebf7fc commit 22420fa

File tree

1 file changed

+163
-176
lines changed

1 file changed

+163
-176
lines changed

packages/vue/src/pager/src/mobile-first.vue

Lines changed: 163 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -1,187 +1,174 @@
11
<template>
22
<div class="text-right py-3 px-0 text-color-text-primary">
3-
<template v-if="internalLayout">
4-
<template v-if="!(hideOnSinglePage && (!internalPageCount || internalPageCount === 1))">
5-
<template v-for="(item, index) in internalLayout.split(',')">
6-
<!-- 总数显示 -->
3+
<template v-for="(item, index) in internalLayout.split(',')">
4+
<!-- 总数显示 -->
5+
<div
6+
v-if="item.trim() === 'total' && typeof internalTotal === 'number'"
7+
:key="'total' + index"
8+
class="inline-block align-middle text-xs h-7 leading-7 float-left"
9+
>
10+
<div v-if="showTotalLoading" class="h-7 leading-7 text-xs text-color-text-primary">
711
<div
8-
v-if="item.trim() === 'total' && typeof internalTotal === 'number'"
9-
:key="'total' + index"
10-
class="inline-block align-middle text-xs h-7 leading-7 float-left"
11-
>
12-
<div v-if="showTotalLoading" class="h-7 leading-7 text-xs text-color-text-primary">
12+
data-tag="tiny-pager-total-loading"
13+
class="inline-block align-baseline h-3.5 w-3.5 mr-1.5 top-0.5 [&_[data-tag=tiny-loading-icon]]:h-3.5 [&_[data-tag=tiny-loading-icon]]:w-3.5"
14+
></div>
15+
<span class="text-color-text-secondary">{{ t('ui.page.loadingTotals') }}</span>
16+
</div>
17+
<div v-else class="h-7 leading-7 text-xs text-color-text-primary">
18+
<span>{{ t('ui.page.total') }}</span>
19+
<span class="my-0 mx-1">
20+
{{ customTotal ? totalText : internalTotal }}
21+
</span>
22+
<span>{{ t('ui.page.item') }}</span>
23+
</div>
24+
</div>
25+
26+
<!-- 每页条数选择器 -->
27+
<div
28+
v-else-if="item.trim() === 'sizes'"
29+
:key="'sizes' + index"
30+
data-tag="tiny-pager-popover"
31+
class="hidden sm:inline-block align-middle text-xs h-7 text-xs text-color-text-primary relative -top-px"
32+
>
33+
<popover
34+
ref="sizesList"
35+
placement="bottom-start"
36+
:append-to-body="popperAppendToBody"
37+
trigger="click"
38+
:popper-class="
39+
'w-24 sm:p-0 sm:!mt-1 sm:!mb-1 data-tag-pager-selector' + (popperClass ? ' ' + popperClass : '')
40+
"
41+
:visible-arrow="false"
42+
:disabled="disabled"
43+
@show="showSizes = true"
44+
@hide="showSizes = false"
45+
>
46+
<template #reference>
47+
<div class="m-0 ml-2" @click.stop>
1348
<div
14-
data-tag="tiny-pager-total-loading"
15-
class="inline-block align-baseline h-3.5 w-3.5 mr-1.5 top-0.5 [&_[data-tag=tiny-loading-icon]]:h-3.5 [&_[data-tag=tiny-loading-icon]]:w-3.5"
16-
></div>
17-
<span class="text-color-text-secondary">{{ t('ui.page.loadingTotals') }}</span>
18-
</div>
19-
<div v-else class="h-7 leading-7 text-xs text-color-text-primary">
20-
<span>{{ t('ui.page.total') }}</span>
21-
<span class="my-0 mx-1">
22-
{{ customTotal ? totalText : internalTotal }}
23-
</span>
24-
<span>{{ t('ui.page.item') }}</span>
25-
</div>
26-
</div>
27-
28-
<!-- 每页条数选择器 -->
29-
<div
30-
v-else-if="item.trim() === 'sizes'"
31-
:key="'sizes' + index"
32-
data-tag="tiny-pager-popover"
33-
class="hidden sm:inline-block align-middle text-xs h-7 text-xs text-color-text-primary relative -top-px"
34-
>
35-
<popover
36-
ref="sizesList"
37-
placement="bottom-start"
38-
:append-to-body="popperAppendToBody"
39-
trigger="click"
40-
:popper-class="
41-
'w-24 sm:p-0 sm:!mt-1 sm:!mb-1 data-tag-pager-selector' + (popperClass ? ' ' + popperClass : '')
42-
"
43-
:visible-arrow="false"
44-
:disabled="disabled"
45-
@show="showSizes = true"
46-
@hide="showSizes = false"
47-
>
48-
<template #reference>
49-
<div class="m-0 ml-2" @click.stop>
50-
<div
51-
ref="pageSize"
52-
:class="[
53-
'min-w-[theme(spacing.18)] max-w-[theme(spacing.40)] relative text-left h-7 leading-7 border border-solid border-color-border rounded text-xs py-0 pr-1 pl-3 block whitespace-nowrap transition-[border] duration-300 outline-0 box-border select-none',
54-
showSizes
55-
? 'border-color-border-focus bg-color-fill-6 text-color-border-focus [&_svg]:rotate-180 [&_svg]:fill-color-brand-hover'
56-
: '',
57-
disabled
58-
? 'bg-color-border-disabled text-color-border cursor-not-allowed [&_svg]:fill-color-icon-disabled [&_svg]:cursor-not-allowed'
59-
: 'bg-color-bg-1 text-color-text-primary hover:bg-color-border-disabled hover:border-color-border active:border-color-border-focus active:bg-color-fill-6 active:text-color-brand'
60-
]"
61-
>
62-
<span class="text-xs mr-1 relative -top-px">{{ internalPageSize }}</span>
63-
<span class="relative -top-px">{{ t('ui.page.page') }}</span>
64-
<div
65-
class="w-7 h-7 leading-7 relative float-right -top-px outline-0 box-border text-center overflow-hidden cursor-pointer"
66-
>
67-
<tiny-icon-chevron-down
68-
class="fill-color-text-primary text-sm absolute top-0 left-0 right-0 bottom-0 m-auto hover:fill-color-icon-hover transition-transform duration-300"
69-
/>
70-
</div>
71-
</div>
49+
ref="pageSize"
50+
:class="[
51+
'min-w-[theme(spacing.18)] max-w-[theme(spacing.40)] relative text-left h-7 leading-7 border border-solid border-color-border rounded text-xs py-0 pr-1 pl-3 block whitespace-nowrap transition-[border] duration-300 outline-0 box-border select-none',
52+
showSizes
53+
? 'border-color-border-focus bg-color-fill-6 text-color-border-focus [&_svg]:rotate-180 [&_svg]:fill-color-brand-hover'
54+
: '',
55+
disabled
56+
? 'bg-color-border-disabled text-color-border cursor-not-allowed [&_svg]:fill-color-icon-disabled [&_svg]:cursor-not-allowed'
57+
: 'bg-color-bg-1 text-color-text-primary hover:bg-color-border-disabled hover:border-color-border active:border-color-border-focus active:bg-color-fill-6 active:text-color-brand'
58+
]"
59+
>
60+
<span class="text-xs mr-1 relative -top-px">{{ internalPageSize }}</span>
61+
<span class="relative -top-px">{{ t('ui.page.page') }}</span>
62+
<div
63+
class="w-7 h-7 leading-7 relative float-right -top-px outline-0 box-border text-center overflow-hidden cursor-pointer"
64+
>
65+
<tiny-icon-chevron-down
66+
class="fill-color-text-primary text-sm absolute top-0 left-0 right-0 bottom-0 m-auto hover:fill-color-icon-hover transition-transform duration-300"
67+
/>
7268
</div>
73-
</template>
74-
<div class="max-h-[theme(spacing.72)] overflow-y-auto overflow-x-hidden">
75-
<ul>
76-
<li
77-
v-for="sizeItem in pageSizes"
78-
:key="String(sizeItem)"
79-
:class="[
80-
'min-h-[theme(spacing.8)] py-0 px-2 leading-8 max-w-full cursor-pointer overflow-hidden text-ellipsis text-center whitespace-nowrap m-1 rounded',
81-
sizeItem === internalPageSize
82-
? 'text-color-brand bg-color-fill-6'
83-
: 'hover:bg-color-bg-2 text-color-text-primary'
84-
]"
85-
:data-value="sizeItem"
86-
:title="String(sizeItem)"
87-
@click="handleSizeChange(Number(sizeItem))"
88-
>
89-
{{ sizeItem }}
90-
</li>
91-
</ul>
9269
</div>
93-
</popover>
70+
</div>
71+
</template>
72+
<div class="max-h-[theme(spacing.72)] overflow-y-auto overflow-x-hidden">
73+
<ul>
74+
<li
75+
v-for="sizeItem in pageSizes"
76+
:key="String(sizeItem)"
77+
:class="[
78+
'min-h-[theme(spacing.8)] py-0 px-2 leading-8 max-w-full cursor-pointer overflow-hidden text-ellipsis text-center whitespace-nowrap m-1 rounded',
79+
sizeItem === internalPageSize
80+
? 'text-color-brand bg-color-fill-6'
81+
: 'hover:bg-color-bg-2 text-color-text-primary'
82+
]"
83+
:data-value="sizeItem"
84+
:title="String(sizeItem)"
85+
@click="handleSizeChange(Number(sizeItem))"
86+
>
87+
{{ sizeItem }}
88+
</li>
89+
</ul>
9490
</div>
95-
96-
<!-- 上一页按钮 -->
97-
<button
98-
v-else-if="item.trim() === 'prev'"
99-
:key="'prev' + index"
100-
type="button"
101-
class="group min-w-[theme(spacing.7)] h-7 text-xs py-0 px-1 text-color-text-primary bg-color-bg-1 rounded-sm outline-0 ml-0 sm:ml-2 align-bottom cursor-pointer hover:border-color-icon-primary disabled:cursor-default"
102-
:disabled="disabled || internalCurrentPage <= 1"
103-
@click="prev"
104-
>
105-
<span
106-
v-if="prevText"
107-
class="group-disabled:text-color-text-disabled group-disabled:cursor-not-allowed group-hover:text-color-icon-hover"
108-
>
109-
{{ prevText }}
110-
</span>
111-
<tiny-icon-chevron-left
112-
v-else
113-
class="align-sub group-disabled:fill-color-icon-disabled group-disabled:cursor-not-allowed group-hover:fill-color-icon-active"
114-
/>
115-
</button>
116-
117-
<!-- 分页器 -->
118-
<pager
119-
v-else-if="item.trim() === 'pager'"
120-
:key="'pager' + index"
121-
:is-before-page-change="isBeforePageChange"
122-
@before-page-change="beforePagerChangeHandler"
123-
:current-page="internalCurrentPage"
124-
:page-count="internalPageCount || 0"
125-
:pager-count="pagerCount"
126-
@change="handleCurrentChange"
91+
</popover>
92+
</div>
93+
94+
<!-- 上一页按钮 -->
95+
<button
96+
v-else-if="item.trim() === 'prev'"
97+
:key="'prev' + index"
98+
type="button"
99+
class="group min-w-[theme(spacing.7)] h-7 text-xs py-0 px-1 text-color-text-primary bg-color-bg-1 rounded-sm outline-0 ml-0 sm:ml-2 align-bottom cursor-pointer hover:border-color-icon-primary disabled:cursor-default"
100+
:disabled="disabled || internalCurrentPage <= 1"
101+
@click="prev"
102+
>
103+
<span
104+
v-if="prevText"
105+
class="group-disabled:text-color-text-disabled group-disabled:cursor-not-allowed group-hover:text-color-icon-hover"
106+
>
107+
{{ prevText }}
108+
</span>
109+
<tiny-icon-chevron-left
110+
v-else
111+
class="align-sub group-disabled:fill-color-icon-disabled group-disabled:cursor-not-allowed group-hover:fill-color-icon-active"
112+
/>
113+
</button>
114+
115+
<!-- 分页器 -->
116+
<pager
117+
v-else-if="item.trim() === 'pager'"
118+
:key="'pager' + index"
119+
:is-before-page-change="isBeforePageChange"
120+
@before-page-change="beforePagerChangeHandler"
121+
:current-page="internalCurrentPage"
122+
:page-count="internalPageCount || 0"
123+
:pager-count="pagerCount"
124+
@change="handleCurrentChange"
125+
:disabled="disabled"
126+
/>
127+
128+
<!-- 下一页按钮 -->
129+
<button
130+
v-else-if="item.trim() === 'next'"
131+
:key="'next' + index"
132+
type="button"
133+
class="group min-w-[theme(spacing.7)] h-7 text-xs py-0 px-1 text-color-text-primary bg-color-bg-1 rounded-sm outline-0 ml-0 sm:ml-2 align-bottom cursor-pointer hover:border-color-icon-primary disabled:cursor-default"
134+
:disabled="disabled || internalCurrentPage === internalPageCount || internalPageCount === 0"
135+
@click="next"
136+
>
137+
<span
138+
v-if="nextText"
139+
class="group-disabled:text-color-text-disabled group-disabled:cursor-not-allowed group-hover:text-color-icon-hover"
140+
>
141+
{{ nextText }}
142+
</span>
143+
<tiny-icon-chevron-right
144+
v-else
145+
class="align-sub group-disabled:fill-color-icon-disabled group-disabled:cursor-not-allowed group-hover:fill-color-icon-active"
146+
/>
147+
</button>
148+
149+
<!-- 跳转器 -->
150+
<div
151+
v-else-if="item.trim() === 'jumper'"
152+
:key="'jumper' + index"
153+
class="h-7 leading-7 inline-block align-middle text-xs"
154+
>
155+
<div class="text-[0] h-7">
156+
<span class="text-xs pl-4 pr-2 text-color-text-primary">{{ t('ui.page.jump') }}</span>
157+
<input
158+
ref="jumperInput"
159+
type="tel"
127160
:disabled="disabled"
161+
class="w-8 h-7 text-center align-top rounded-sm inline-block border border-solid border-color-border hover:text-color-icon-primary hover:border-color-icon-primary text-color-text-primary text-xs transition-[border] duration-300 outline-0 box-border mr-0 focus:border-color-border-focus"
162+
:value="jumperValue"
163+
@focus="handleJumperFocus"
164+
@input="handleJumperInput"
165+
@change="handleJumperChange"
128166
/>
167+
</div>
168+
</div>
129169

130-
<!-- 下一页按钮 -->
131-
<button
132-
v-else-if="item.trim() === 'next'"
133-
:key="'next' + index"
134-
type="button"
135-
class="group min-w-[theme(spacing.7)] h-7 text-xs py-0 px-1 text-color-text-primary bg-color-bg-1 rounded-sm outline-0 ml-0 sm:ml-2 align-bottom cursor-pointer hover:border-color-icon-primary disabled:cursor-default"
136-
:disabled="disabled || internalCurrentPage === internalPageCount || internalPageCount === 0"
137-
@click="next"
138-
>
139-
<span
140-
v-if="nextText"
141-
class="group-disabled:text-color-text-disabled group-disabled:cursor-not-allowed group-hover:text-color-icon-hover"
142-
>
143-
{{ nextText }}
144-
</span>
145-
<tiny-icon-chevron-right
146-
v-else
147-
class="align-sub group-disabled:fill-color-icon-disabled group-disabled:cursor-not-allowed group-hover:fill-color-icon-active"
148-
/>
149-
</button>
150-
151-
<!-- 跳转器 -->
152-
<div
153-
v-else-if="item.trim() === 'jumper'"
154-
:key="'jumper' + index"
155-
class="h-7 leading-7 inline-block align-middle text-xs"
156-
>
157-
<div class="text-[0] h-7">
158-
<span class="text-xs pl-4 pr-2 text-color-text-primary">{{ t('ui.page.jump') }}</span>
159-
<input
160-
ref="jumperInput"
161-
type="tel"
162-
:disabled="disabled"
163-
class="w-8 h-7 text-center align-top rounded-sm inline-block border border-solid border-color-border hover:text-color-icon-primary hover:border-color-icon-primary text-color-text-primary text-xs transition-[border] duration-300 outline-0 box-border mr-0 focus:border-color-border-focus"
164-
:value="jumperValue"
165-
@focus="handleJumperFocus"
166-
@input="handleJumperInput"
167-
@change="handleJumperChange"
168-
/>
169-
</div>
170-
</div>
171-
172-
<!-- 默认插槽 -->
173-
<slot v-else-if="item.trim() === 'slot'" :key="'slot' + index">
174-
<template v-if="$parent?.$slots.default">
175-
<template v-if="typeof $parent.$slots.default === 'function'">
176-
{{ $parent.$slots.default() }}
177-
</template>
178-
<template v-else>
179-
{{ $parent.$slots.default }}
180-
</template>
181-
</template>
182-
</slot>
183-
</template>
184-
</template>
170+
<!-- 默认插槽 -->
171+
<slot v-else-if="item.trim() === 'slot'" :key="'slot' + index"></slot>
185172
</template>
186173
</div>
187174
</template>
@@ -270,7 +257,7 @@ export default defineComponent({
270257
changeCompat: Boolean
271258
},
272259
setup(props, { emit }) {
273-
const { ref, reactive, computed, watch, onMounted, nextTick } = hooks
260+
const { ref, reactive, computed, watch, onMounted, nextTick, toRefs } = hooks
274261
const sizesList = ref<{ hide: () => void } | null>(null)
275262
276263
// 响应式数据
@@ -767,7 +754,7 @@ export default defineComponent({
767754
768755
return {
769756
// 状态
770-
...state,
757+
...toRefs(state),
771758
// 方法
772759
t,
773760
handleJumperFocus,

0 commit comments

Comments
 (0)