@ -0,0 +1,465 @@
< template >
< view class = "uni-pagination" >
<!-- # ifndef MP -- >
< picker v-if = "showPageSize === true || showPageSize === 'true'" class="select-picker" mode="selector"
:value = "pageSizeIndex" :range = "pageSizeRange" @change ="pickerChange" @cancel ="pickerClick"
@click.native ="pickerClick" >
< button type = "default" size = "mini" :plain = "true" >
< text > { { pageSizeRange [ pageSizeIndex ] } } { { piecePerPage } } < / text >
< uni-icons class = "select-picker-icon" type = "arrowdown" size = "12" color = "#999" > < / uni-icons >
< / button >
< / picker >
<!-- # endif -- >
<!-- # ifndef APP - NVUE -- >
< view class = "uni-pagination__total is-phone-hide" > 共 { { total } } 条 < / view >
<!-- # endif -- >
< view class = "uni-pagination__btn"
: class = "currentIndex === 1 ? 'uni-pagination--disabled' : 'uni-pagination--enabled'"
: hover -class = " currentIndex = = = 1 ? ' ' : ' uni -pagination - -hover ' " :hover-start-time = "20"
:hover-stay-time = "70" @click ="clickLeft" >
< template v-if = "showIcon === true || showIcon === 'true'" >
< uni -icons color = "#666" size = "16" type = "left" / >
< / template >
< template v-else >
< text class = "uni-pagination__child-btn" > { { prevPageText } } < / text >
< / template >
< / view >
< view class = "uni-pagination__num uni-pagination__num-flex-none" >
< view class = "uni-pagination__num-current" >
< text class = "uni-pagination__num-current-text is-pc-hide current-index-text" > { { currentIndex } } < / text >
< text class = "uni-pagination__num-current-text is-pc-hide" > / { { maxPage || 0 } } < / text >
<!-- # ifndef APP - NVUE -- >
< view v-for = "(item, index) in paper" :key="index" :class="{ 'page--active': item === currentIndex }"
class = "uni-pagination__num-tag tag--active is-phone-hide" @click.top ="selectPage(item, index)" >
< text > { { item } } < / text >
< / view >
<!-- # endif -- >
< / view >
< / view >
< view class = "uni-pagination__btn"
: class = "currentIndex >= maxPage ? 'uni-pagination--disabled' : 'uni-pagination--enabled'"
: hover -class = " currentIndex = = = maxPage ? ' ' : ' uni -pagination - -hover ' " :hover-start-time = "20"
:hover-stay-time = "70" @click ="clickRight" >
< template v-if = "showIcon === true || showIcon === 'true'" >
< uni -icons color = "#666" size = "16" type = "right" / >
< / template >
< template v-else >
< text class = "uni-pagination__child-btn" > { { nextPageText } } < / text >
< / template >
< / view >
< / view >
< / template >
< script >
/**
* Pagination 分页器
* @description 分页器组件,用于展示页码、请求数据等
* @tutorial https://ext.dcloud.net.cn/plugin?id=32
* @property {String} prevText 左侧按钮文字
* @property {String} nextText 右侧按钮文字
* @property {String} piecePerPageText 条/页文字
* @property {Number} current 当前页
* @property {Number} total 数据总量
* @property {Number} pageSize 每页数据量
* @property {Boolean} showIcon = [true|false] 是否以 icon 形式展示按钮
* @property {Boolean} showPageSize = [true|false] 是否展示每页条数
* @property {Array} pageSizeRange = [20, 50, 100, 500] 每页条数选框
* @event {Function} change 点击页码按钮时触发 ,e={type,current} current为当前页, type值为: next/prev, 表示点击的是上一页还是下一个
* * @event {Function} pageSizeChange 当前每页条数改变时触发 ,e={pageSize} pageSize 为当前所选的每页条数
*/
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from './i18n/index.js'
const {
t
} = initVueI18n ( messages )
export default {
name : 'UniPagination' ,
emits : [ 'update:modelValue' , 'input' , 'change' , 'pageSizeChange' ] ,
props : {
value : {
type : [ Number , String ] ,
default : 1
} ,
modelValue : {
type : [ Number , String ] ,
default : 1
} ,
prevText : {
type : String ,
} ,
nextText : {
type : String ,
} ,
piecePerPageText : {
type : String
} ,
current : {
type : [ Number , String ] ,
default : 1
} ,
total : {
// 数据总量
type : [ Number , String ] ,
default : 0
} ,
pageSize : {
// 每页数据量
type : [ Number , String ] ,
default : 10
} ,
showIcon : {
// 是否以 icon 形式展示按钮
type : [ Boolean , String ] ,
default : false
} ,
showPageSize : {
// 是否以 icon 形式展示按钮
type : [ Boolean , String ] ,
default : false
} ,
pagerCount : {
type : Number ,
default : 7
} ,
pageSizeRange : {
type : Array ,
default : ( ) => [ 20 , 50 , 100 , 500 ]
}
} ,
data ( ) {
return {
pageSizeIndex : 0 ,
currentIndex : 1 ,
paperData : [ ] ,
pickerShow : false
}
} ,
computed : {
piecePerPage ( ) {
return this . piecePerPageText || t ( 'uni-pagination.piecePerPage' )
} ,
prevPageText ( ) {
return this . prevText || t ( 'uni-pagination.prevText' )
} ,
nextPageText ( ) {
return this . nextText || t ( 'uni-pagination.nextText' )
} ,
maxPage ( ) {
let maxPage = 1
let total = Number ( this . total )
let pageSize = Number ( this . pageSize )
if ( total && pageSize ) {
maxPage = Math . ceil ( total / pageSize )
}
return maxPage
} ,
paper ( ) {
const num = this . currentIndex
// TODO 最大页数
const pagerCount = this . pagerCount
// const total = 181
const total = this . total
const pageSize = this . pageSize
let totalArr = [ ]
let showPagerArr = [ ]
let pagerNum = Math . ceil ( total / pageSize )
for ( let i = 0 ; i < pagerNum ; i ++ ) {
totalArr . push ( i + 1 )
}
showPagerArr . push ( 1 )
const totalNum = totalArr [ totalArr . length - ( pagerCount + 1 ) / 2 ]
totalArr . forEach ( ( item , index ) => {
if ( ( pagerCount + 1 ) / 2 >= num ) {
if ( item < pagerCount + 1 && item > 1 ) {
showPagerArr . push ( item )
}
} else if ( num + 2 <= totalNum ) {
if ( item > num - ( pagerCount + 1 ) / 2 && item < num + ( pagerCount + 1 ) / 2 ) {
showPagerArr . push ( item )
}
} else {
if ( ( item > num - ( pagerCount + 1 ) / 2 || pagerNum - pagerCount < item ) && item < totalArr [
totalArr . length - 1 ] ) {
showPagerArr . push ( item )
}
}
} )
if ( pagerNum > pagerCount ) {
if ( ( pagerCount + 1 ) / 2 >= num ) {
showPagerArr [ showPagerArr . length - 1 ] = '...'
} else if ( num + 2 <= totalNum ) {
showPagerArr [ 1 ] = '...'
showPagerArr [ showPagerArr . length - 1 ] = '...'
} else {
showPagerArr [ 1 ] = '...'
}
showPagerArr . push ( totalArr [ totalArr . length - 1 ] )
} else {
if ( ( pagerCount + 1 ) / 2 >= num ) { } else if ( num + 2 <= totalNum ) { } else {
showPagerArr . shift ( )
showPagerArr . push ( totalArr [ totalArr . length - 1 ] )
}
}
return showPagerArr
}
} ,
watch : {
current : {
immediate : true ,
handler ( val , old ) {
if ( val < 1 ) {
this . currentIndex = 1
} else {
this . currentIndex = val
}
}
} ,
value : {
immediate : true ,
handler ( val ) {
if ( Number ( this . current ) !== 1 ) return
if ( val < 1 ) {
this . currentIndex = 1
} else {
this . currentIndex = val
}
}
} ,
pageSizeIndex ( val ) {
this . $emit ( 'pageSizeChange' , this . pageSizeRange [ val ] )
}
} ,
methods : {
pickerChange ( e ) {
this . pageSizeIndex = e . detail . value
this . pickerClick ( )
} ,
pickerClick ( ) {
// #ifdef H5
const body = document . querySelector ( 'body' )
if ( ! body ) return
const className = 'uni-pagination-picker-show'
this . pickerShow = ! this . pickerShow
if ( this . pickerShow ) {
body . classList . add ( className )
} else {
setTimeout ( ( ) => body . classList . remove ( className ) , 300 )
}
// #endif
} ,
// 选择标签
selectPage ( e , index ) {
if ( parseInt ( e ) ) {
this . currentIndex = e
this . change ( 'current' )
} else {
let pagerNum = Math . ceil ( this . total / this . pageSize )
// let pagerNum = Math.ceil(181 / this.pageSize)
// 上一页
if ( index <= 1 ) {
if ( this . currentIndex - 5 > 1 ) {
this . currentIndex -= 5
} else {
this . currentIndex = 1
}
return
}
// 下一页
if ( index >= 6 ) {
if ( this . currentIndex + 5 > pagerNum ) {
this . currentIndex = pagerNum
} else {
this . currentIndex += 5
}
return
}
}
} ,
clickLeft ( ) {
if ( Number ( this . currentIndex ) === 1 ) {
return
}
this . currentIndex -= 1
this . change ( 'prev' )
} ,
clickRight ( ) {
if ( Number ( this . currentIndex ) >= this . maxPage ) {
return
}
this . currentIndex += 1
this . change ( 'next' )
} ,
change ( e ) {
this . $emit ( 'input' , this . currentIndex )
this . $emit ( 'update:modelValue' , this . currentIndex )
this . $emit ( 'change' , {
type : e ,
current : this . currentIndex
} )
}
}
}
< / script >
< style lang = "scss" scoped >
$uni - primary : # 2979 ff ! default ;
. uni - pagination {
/* #ifndef APP-NVUE */
display : flex ;
/* #endif */
position : relative ;
overflow : hidden ;
flex - direction : row ;
justify - content : center ;
align - items : center ;
}
. uni - pagination _ _total {
font - size : 14 px ;
color : # 999 ;
margin - right : 15 px ;
}
. uni - pagination _ _btn {
/* #ifndef APP-NVUE */
display : flex ;
cursor : pointer ;
/* #endif */
padding : 0 8 px ;
line - height : 30 px ;
font - size : 12 px ;
position : relative ;
background - color : # F0F0F0 ;
flex - direction : row ;
justify - content : center ;
align - items : center ;
text - align : center ;
border - radius : 5 px ;
// border-width: 1px;
// border-style: solid;
// border-color: $uni-border-color;
}
. uni - pagination _ _child - btn {
/* #ifndef APP-NVUE */
display : flex ;
/* #endif */
font - size : 12 px ;
position : relative ;
flex - direction : row ;
justify - content : center ;
align - items : center ;
text - align : center ;
color : # 666 ;
font - size : 12 px ;
}
. uni - pagination _ _num {
/* #ifndef APP-NVUE */
display : flex ;
/* #endif */
flex : 1 ;
flex - direction : row ;
justify - content : center ;
align - items : center ;
height : 30 px ;
line - height : 30 px ;
font - size : 12 px ;
color : # 666 ;
margin : 0 5 px ;
}
. uni - pagination _ _num - tag {
/* #ifdef H5 */
cursor : pointer ;
min - width : 30 px ;
/* #endif */
margin : 0 5 px ;
height : 30 px ;
text - align : center ;
line - height : 30 px ;
// border: 1px red solid;
color : # 999 ;
border - radius : 4 px ;
// border-width: 1px;
// border-style: solid;
// border-color: $uni-border-color;
}
. uni - pagination _ _num - current {
/* #ifndef APP-NVUE */
display : flex ;
/* #endif */
flex - direction : row ;
}
. uni - pagination _ _num - current - text {
font - size : 15 px ;
}
. current - index - text {
color : $uni - primary ;
}
. uni - pagination -- enabled {
color : # 333333 ;
opacity : 1 ;
}
. uni - pagination -- disabled {
opacity : 0.5 ;
/* #ifdef H5 */
cursor : default ;
/* #endif */
}
. uni - pagination -- hover {
color : rgba ( 0 , 0 , 0 , 0.6 ) ;
background - color : # eee ;
}
. tag -- active : hover {
color : $uni - primary ;
}
. page -- active {
color : # fff ;
background - color : $uni - primary ;
}
. page -- active : hover {
color : # fff ;
}
/* #ifndef APP-NVUE */
. is - pc - hide {
display : block ;
}
. is - phone - hide {
display : none ;
}
@ media screen and ( min - width : 450 px ) {
. is - pc - hide {
display : none ;
}
. is - phone - hide {
display : block ;
}
. uni - pagination _ _num - flex - none {
flex : none ;
}
}
/* #endif */
< / style >