需求分析
- 支持傳入當前頁碼參數並展示;
- 支持頁數過多的部分用省略號顯示,並會動態變化;
- 支持支持點擊左右方向鍵切換頁碼;
- 支持在只有一頁的時候隱藏pager;
方法實現
1、pager外部組件傳參定義:
一共可傳4個參數:
- total,頁碼條數
- current,當前頁碼
- current.sync,點擊頁碼的current參數回調
- hide-one-page, 默認不填一頁時顯示,false則隱藏
<T-pager :total="10" :current="1" :current.sync="currentPage" :hide-one-page="false"></T-pager>
2、pager組件內部實現:
HTML
<template>
<div class="pager-content" :class="{hide: !hideOnePage && pages <= 1}">
<span class="pager-content-nav prev"
@click="onClickPage(current-1)"
:class="{disabled: current === 1}">
<t-icon name="left"></t-icon>
</span>
<template v-for="page in pages">
<template v-if="page === current">
<span class="pager-content-item current">{{page}}</span>
</template>
<template v-else-if="page === '...'">
<span class="pager-content-item separator">...</span>
</template>
<template v-else>
<span class="pager-content-item other" @click="onClickPage(page)">{{page}}</span>
</template>
</template>
<span class="pager-content-nav next"
@click="onClickPage(current+1)"
:class="{disabled: current === total}">
<t-icon name="right"></t-icon>
</span>
</div>
</template>
JS
<script>
import TIcon from '../icon'
export default {
name: 'pager',
components: {
TIcon
},
props: {
total: {
type: Number,
default: 1
},
current: {
type: Number,
default: 1
},
hideOnePage: {
type: Boolean,
default: true
}
},
computed: {
pages() {
let pages = [1, this.total, this.current, this.current-1, this.current-2, this.current+1, this.current+2]
let u = pages.filter(n => n >= 1 && n <= this.total)
let u1 = this.unique(u.sort((a, b) => a - b))
return u1.reduce((a, b, index, array) => { // 過濾,添加...
a.push(b)
if (array[index + 1] !== undefined && array[index+1] - array[index] > 1) {
a.push('...')
}
return a
}, [])
}
},
methods: {
onClickPage(n) {
if (n >=1 && n <= this.total) {
this.$emit('update:current', n)
}
},
unique(array) { //數組去重
const object = {}
array.map(item => {
object[item] = true
})
return Object.keys(object).map(value => parseInt(value, 10))
}
}
}
</script>
- 省略號:通過計算屬性pages,四重遍歷動態計算出省略號的位置,小於5條total則不展示省略號。
- 監聽pager點擊結構樣式變化:onClickPage()方法,將變化的數據傳出去,再通過current.sync接收,更新current的值,從而達到單向數據流的目的,實現功能的同時,還可簡化邏輯。
- 一頁樣式隱藏:通過css類做判斷即可。
- 左右方向箭頭切換:增加或減少current的值即可,但要留意邊界情況(小於1條大於最後一條),最後走‘update:current’單向數據流出發外部current參數回調即可。
3、在v-for中使用不同標籤展示數據的方法:
參考下面的HTML代碼,只需通過template模板遍歷即可。應爲template模板標籤在瀏覽器渲染中不會變成標籤。
<template v-for="page in pages">
<template v-if="page === current">
<span class="pager-content-item current">{{page}}</span>
</template>
<template v-else-if="page === '...'">
<div class="pager-content-item separator">...</div>
</template>
<template v-else>
<a class="pager-content-item other" @click="onClickPage(page)">{{page}}</a>
</template>
</template>