当前位置:网站首页>Handwriting sorter component
Handwriting sorter component
2022-06-30 09:10:00 【Ancient dust left Taidao】
The theme
When the amount of data is too large , Front end paging is unavoidable , Record a handwritten pager component ( It is estimated that I will only write it once in my life ).
First, get the static pager out . Do it again js logic design .
<template>
<div class="pagination">
<button> The previous page </button>
<button>1</button>
<button>···</button>
<button>3</button>
<button>4</button>
<button>5</button>
<button>6</button>
<button>7</button>
<button>···</button>
<button>9</button>
<button> The next page </button>
<button style="margin-left: 30px"> common 60 strip </button>
</div>
</template>
<script>
export default {
name: 'Pagination'
}
</script>
<style lang="less" scoped>
.pagination {
text-align: center;
button {
margin: 0 5px;
background-color: #f4f4f5;
color: #606266;
outline: none;
border-radius: 2px;
padding: 0 4px;
vertical-align: top;
display: inline-block;
font-size: 13px;
min-width: 35.5px;
height: 28px;
line-height: 28px;
cursor: pointer;
box-sizing: border-box;
text-align: center;
border: 0;
&[disabled] {
color: #c0c4cc;
cursor: not-allowed;
}
&.active {
cursor: not-allowed;
background-color: #409eff;
color: #fff;
}
}
}
</style>
View :

Parametric design
First of all, we need to figure out a few things , What do we need for front-end paging ? Here, let's assume that we are doing a shopping mall project .
- 1.
total: The total quantity of goods - 2.
pageSize: Number of pages to be displayed - 3.
curPage: The current page
Then I designed the pager , The middle lump , Default display 5 individual , That is to say, the current page also has 2 A page number
After figuring out what we want , We pass some parameter tests in the parent component .
Parent component use
<Pagination :total="30" :curPage="6" :pageSize="10"></Pagination>
Subcomponents accept
props: {
// The total quantity of goods
total: {
type: Number,
default: 0
},
// The current page
curPage: {
type: Number,
default: 1
},
// The size of each page
pageSize: {
type: Number,
default: 10
}
}
And that's the problem , How many pages are there ? Let's calculate first , If total by 90, The number of items per page is 10 individual , Then the page number has 9 individual , But if total yes 91 Well ? Then the page number should have 10 individual , Obviously , yes Divide the total by the number of pages And take up the whole . So we can create one in the pager component pageTotalNum, Because it depends on total and pageSize Of , So we can put it in the calculation properties here .
computed: {
// The total number of pages
pageTotalNum () {
return Math.ceil(this.total / this.pageSize)
}
}
Write here , So let's test that out
Parent component parameters
<Pagination :total="300" :curPage="6" :pageSize="10"></Pagination>
Upper component code
<template>
<div class="pagination">
<button> The previous page </button>
<button>1</button>
<button>···</button>
<button>3</button>
<button>4</button>
<button>5</button>
<button>6</button>
<button>7</button>
<button>···</button>
<button>{
{ pageTotalNum }}</button>
<button> The next page </button>
<span> common {
{ total }} strip </span>
</div>
</template>
<script>
export default {
name: 'Pagination',
props: {
// The total quantity of goods
total: {
type: Number,
default: 0
},
// The current page
curPage: {
type: Number,
default: 1
},
// The size of each page
pageSize: {
type: Number,
default: 10
}
},
computed: {
pageTotalNum () {
return Math.ceil(this.total / this.pageSize)
}
}
}
</script>
<style lang="less" scoped>
.pagination {
text-align: center;
span,
button {
margin: 0 5px;
background-color: #f4f4f5;
color: #606266;
outline: none;
border-radius: 2px;
padding: 0 4px;
vertical-align: top;
display: inline-block;
font-size: 13px;
min-width: 35.5px;
height: 28px;
line-height: 28px;
cursor: pointer;
box-sizing: border-box;
text-align: center;
border: 0;
&[disabled] {
color: #c0c4cc;
cursor: not-allowed;
}
&.active {
cursor: not-allowed;
background-color: #409eff;
color: #fff;
}
}
span {
cursor: none !important;
background-color: unset !important;
}
}
</style>
View :

succeed , Actually measured total by 301 No problem , I won't take a screenshot here .
Dealing with border situations
It seems that the pager component is well designed , There is nothing wrong with the view , But there are still many boundary conditions to deal with .
1. Current page number problem
First of all, we have to figure out one thing , If the current page number is 5, that 5 There must be 2 Of consecutive pages , That is, if the middle lump 3,4,5,6,7, But the problem is , If the current page number is 2 Well , It can never be 0,1,2,3,4,5 Well , Therefore, the current page number has relevant restrictions , That is to say, when The current page number Less than 3 when , Special treatment is needed , Because the current page number is equal to 3, just 1,2,3,4,5.
1.1 The starting parameter of the middle lump
At this point we define a start Parameters , Used to indicate the front of the current page number 2 A page number , in other words , The current page number is 5, that start Namely 3, The current page number is 4,start Is is 2
At this time, we have to deal with the relevant logic
// Before the current page number 2 position
start () {
// The current page number is less than 3, Left right asymmetry ,start Directly for 1
if (this.curPage < 3) {
return 1
} else {
return this.curPage - 2
}
}
1.2 The end parameter of the middle lump
At this point we define a end Parameters , Used to represent the last... Of the current page number 2 A page number , in other words , The current page number is 5, that end Namely 7, The current page number is 4,end Is is 6
At this time, we have to deal with the relevant logic . This place is a little troublesome , For example, the total number of pages is now 8, The current page number is 7,end Certainly not for 9 Is for 8, The current page number is 6,end Just normal , So to launch end Less than the total number of pages -2 To display properly .
end () {
// The current page number cannot be greater than the total page number -2
if (this.curPage > this.pageTotalNum - 2) {
return this.pageTotalNum
} else {
return this.curPage + 2
}
}
Loop through the middle button
We now have the button in the middle start and end Parameters , You can use the button in the middle v-for Loop traversal comes out
<button v-for="(item, index) in end" :key="index">
{
{ item }}
</button>
View :

Obviously , Traversal is traversal out , But there is clearly a problem , There are obviously too many buttons in the middle of us , The expectation should be 4,5,6,7,8,----1,2,3 It should not be displayed , That's where it comes in v-if 了 , The logic of judgment is that I only let start Less than or equal to item Display of , That's all right. . But here's one thing to note ,v-if and v-for Can not be used together , Please refer to my article on how to solve this problem article ,
On html Code
<template v-for="(item, index) in end">
<button v-if="start <= item" :key="index">
{
{ item }}
</button>
</template>
Upper view :

It looks like it's normal .
Reprocessing of boundary conditions
1. The boundary case on the left
But here it is again , The front one 1 Follow … Certainly not always , For example, if start yes 1 Well ? View :

Consider the left side first … Show and hide , We think about , When start by 3 when ,1 Follow 3 There's one in the middle 2, Now … It should show , When statr by 2 when ,… It should be hidden so … Display and hide logic of
<button v-show="start > 2">···</button>
View :

Um. , Very much in line with our expectations .
On top 1 The logic of judgment
<button v-show="start > 1">1</button>
View :

It is also in line with our expectations .
2. The boundary case on the right
Let's consider the one on the right … Show and hide , When end be equal to 30 When , No, …, When end be equal to 29 When there is …
Then the judgment logic comes out
<button v-show="end < pageTotalNum - 1">···</button>
The view is also as expected , Notice that I changed the current page number here to 28

Control again 31 Show and hide , Think about it , If end be equal to 31 that 31 It must be hidden
<button v-show="end !== pageTotalNum">{
{ pageTotalNum }}</button>
Notice here that I changed the current page number to 29 Give Way end Equal to the total number of pages
The view is also as expected :

3. Disable the previous page and next page buttons
imagine :
- The current page is on the first page , You can't click on the previous page
- The current page is the last , You can't click on the next page
This place is relatively simple to use the judgment code
<button :disabled="curPage === 1"> The previous page </button>
<button :disabled="curPage === pageTotalNum"> The next page </button>
Come here , The boundary situation is over . We started designing interaction logic
Click the event binding
The event binding of the button
Click which page number to modify the page number value in the parent component , My idea here is to use the sub component to emit events and the parent component to handle page number modification , Because the current page number is passed from the parent component to the child component , Then it must involve the child component modifying the value of the parent component , So I take the following approach , Upper parent component code
<Pagination :total="301" :cur-page="curPage" :page-size="10" @current-page=“currentPage” ></Pagination>
curPage The initial value of must be 1, The button in the middle html Code
<template v-for="(item, index) in end">
<button v-if="start <= item" :key="index" @click="changeCurrentPage(item)" >
{
{ item }}
</button>
</template>
Event handling :
methods: {
changeCurrentPage (curPage) {
this.$emit('current-page', curPage)
}
},
After actual testing , No problem .
Others are The previous page , The next page , first page , The last page Button logic , Give the template area code directly
<template>
<div class="pagination">
<button :disabled="curPage === 1" @click="changeCurrentPage(curPage - 1)">
The previous page
</button>
<button v-show="start > 1" @click="changeCurrentPage(1)">1</button>
<button v-show="start > 2">···</button>
<template v-for="(item, index) in end">
<button v-if="start <= item" :key="index" @click="changeCurrentPage(item)" >
{
{ item }}
</button>
</template>
<button v-show="end < pageTotalNum - 1">···</button>
<button v-show="end !== pageTotalNum" @click="changeCurrentPage(pageTotalNum)" >
{
{ pageTotalNum }}
</button>
<button :disabled="curPage === pageTotalNum" @click="changeCurrentPage(curPage + 1)" >
The next page
</button>
<span> common {
{ total }} strip </span>
</div>
</template>
Activate style binding
<template v-for="(item, index) in end">
<button :class="{ active: curPage === index + 1 }" v-if="start <= item" :key="index" @click="changeCurrentPage(item)" >
{
{ item }}
</button>
</template>
Determine the current page number and index+1 Whether it is equal or not , Be careful , The page number is from 1 At the beginning index It's from 0 At the beginning , therefore index Add 1
I won't give you the style , You can customize it yourself .
Code optimization
Let's think about it , If the user clicks the current page , In fact, there is no need to send a network request to render the interface , So we can optimize it in the click event
changeCurrentPage (curPage) {
// If the user clicks the current page number , Don't make a request
if (this.curPage === curPage) {
return ''
}
this.$emit('current-page', curPage)
}
Complete component code
<template>
<div class="pagination">
<button :disabled="curPage === 1" @click="changeCurrentPage(curPage - 1)">
The previous page
</button>
<button v-show="start > 1" @click="changeCurrentPage(1)">1</button>
<button v-show="start > 2" style="cursor: unset">···</button>
<template v-for="(item, index) in end">
<button
:class="{ active: curPage === index + 1 }"
v-if="start <= item"
:key="index"
@click="changeCurrentPage(item)"
>
{
{ item }}
</button>
</template>
<button v-show="end < pageTotalNum - 1" style="cursor: unset">···</button>
<button
v-show="end !== pageTotalNum"
@click="changeCurrentPage(pageTotalNum)"
>
{
{ pageTotalNum }}
</button>
<button
:disabled="curPage === pageTotalNum"
@click="changeCurrentPage(curPage + 1)"
>
The next page
</button>
<span> common {
{ total }} strip </span>
</div>
</template>
<script>
export default {
name: 'Pagination',
props: {
// The total quantity of goods
total: {
type: Number,
default: 0
},
// The current page
curPage: {
type: Number,
default: 1
},
// The size of each page
pageSize: {
type: Number,
default: 10
}
},
methods: {
changeCurrentPage (curPage) {
if (this.curPage === curPage) {
return ''
}
this.$emit('current-page', curPage)
}
},
computed: {
// Total page number
pageTotalNum () {
return Math.ceil(this.total / this.pageSize)
},
// Before the current page number 2 position
start () {
// The current page number is less than 3, Left right asymmetry ,start Directly for 1
if (this.curPage < 3) {
return 1
} else {
return this.curPage - 2
}
},
// After the current page number 2 position
end () {
// The current page number cannot be greater than the total page number -2
if (this.curPage > this.pageTotalNum - 2) {
return this.pageTotalNum
} else {
return this.curPage + 2
}
}
}
}
</script>
<style lang="less" scoped>
.pagination {
text-align: center;
span,
button {
margin: 0 5px;
background-color: #f4f4f5;
color: #606266;
outline: none;
border-radius: 2px;
padding: 0 4px;
vertical-align: top;
display: inline-block;
font-size: 13px;
min-width: 35.5px;
height: 28px;
line-height: 28px;
cursor: pointer;
box-sizing: border-box;
text-align: center;
border: 0;
&[disabled] {
color: #c0c4cc;
cursor: not-allowed;
}
}
span {
cursor: none !important;
background-color: unset !important;
}
.active {
background-color: #409eff;
color: #fff;
cursor: unset;
}
}
</style>
summary
This paging component can be transferred to 3 Parameters
1.
total: The total quantity of goods2.
pageSize: Number of pages to be displayed3.
curPage: The current pageThis component can send an event to the parent component when the page number changes , Event name :
current-page, Callback Arguments , The currently clicked page number .If there are any questions , Welcome to point out ~~~~
Blog
Welcome to my blog www.smartxy.cc
边栏推荐
- Flink Sql -- toAppendStream doesn‘t support consuming update and delete changes which
- 使用华为性能管理服务,按需配置采样率
- Flink sql -- No factory implements ‘org. apache. flink. table. delegation. ExecutorFactory‘.
- 基于Svelte3.x桌面端UI组件库Svelte UI
- Abstract factory pattern
- Opencv learning notes -day8 (keyboard typing (waitkey()); Wait for typing) action: triggers some action when the appropriate character is typed using the keyboard)
- 127.0.0.1, 0.0.0.0 and localhost
- C # get the current timestamp
- Harmonyos actual combat - ten thousand words long article understanding service card development process
- 【付费推广】常见问题合集,推荐榜单FAQ
猜你喜欢

Abstract factory pattern

Duplicate entry '2' for key 'primary appears in JPA‘

The elegant combination of walle and Jianbao

Wechat development tool (applet)

将线程绑定在某个具体的CPU逻辑内核上运行

Implementing custom drawer component in quick application

100 lines of code and a voice conversation assistant

C accesses mongodb and performs CRUD operations

Rew acoustic test (III): generate test signal

Opencv learning notes-day5 (arithmetic operation of image pixels, add() addition function, subtract() subtraction function, divide() division function, multiply() multiplication function
随机推荐
Understanding of MVVM and MVC
证券开户的优惠怎样才能得到?在线开户安全?
Detailed explanation of pipline of mmdetection
mysql基础入门 day3 动力节点[老杜]课堂笔记
Opencv learning notes -day10 logical operation of image pixels (usage of rectangle function and rect function and bit related operation in openCV)
JVM tuning related commands and explanations
Detailed explanation of rect class
Opencv learning notes-day6-7 (scroll bar operation demonstration is used to adjust image brightness and contrast, and createtrackbar() creates a scroll bar function)
Treatment process record of Union Medical College Hospital (Dongdan hospital area)
Flink Sql -- toAppendStream doesn‘t support consuming update and delete changes which
Opencv learning notes -day13 pixel value statistics calculation of maximum and minimum values, average values and standard deviations (use of minmaxloc() and meanstddev() functions)
启动jar包报错UnsupportedClassVersionError,如何修复
Comparison of two ways for C to access SQL Server database (SqlDataReader vs SqlDataAdapter)
asdsadadsad
[untitled]
Alcohol tester scheme: what principle does the alcohol tester measure alcohol solubility based on?
Detectron2 source code reading 3-- encapsulating dataset with mapper
Application of hongruan face recognition
About MySQL Boolean and tinyint (1)
Esp32 things (II): sharpening the knife without mistaking firewood - make preparations before project development