先上一波效果圖:javascript
首先,翻頁組件(如下稱「pager
組件」)通常擁有的元素有:html
上一頁vue
第一頁java
中間顯示的頁碼git
最後一頁github
下一頁vue-router
初始化時須要的配置有:vuex
totalPage
(總頁數)數組
initPage
(初始頁)app
showPrev
(是否顯示上一頁)
showNext
(是否顯示下一頁)
showItems
(中間顯示幾頁)
showJump
(是否顯示跳轉到第幾頁)
這些能夠經過vue
的props
來接收。
另外,pager
組件自己須要有一個記錄當前頁的currentPage
,pages
數組用來容納中間顯示的頁碼,jumpPage
綁定輸入的跳轉頁碼。
對應的代碼爲:
<template> <div class="pager-wrapper" v-if="totalPage > 0"> <div class="pager-pages"> <a v-show="currentPage > 1 && showPrev" @click="go(currentPage - 1)">上一頁</a> <a :class="{active: currentPage == 1 ? true : false}" @click="go(1)">1</a> <strong v-show="pages[0] > 2">...</strong> <a v-for="page in pages" :class="{active: currentPage == page ? true : false}" @click="go(page)">{{page}}</a> <strong v-show="pages[pages.length-1] < totalPage - 1">...</strong> <a v-if="totalPage > 1" :class="{active: currentPage == totalPage ? true : false}" @click="go(totalPage)">{{totalPage}}</a> <a v-show="currentPage < totalPage && showNext" @click="go(currentPage + 1)">下一頁</a> </div> <div v-if="showJump" v-show="totalPage > 1" class="pager-jump"> <span>共<em class="jump-total">{{totalPage}}</em>頁 ,跳至</span> <input type="number" min="1" :max="totalPage" v-model="jumpPage" class="jump-input"> <span>頁</span> <a @click="go(jumpPage)">肯定</a> </div> </div> </template> <script> export default { props: { totalPage: { // 總頁數 type: Number, default: 1, required: true }, showItems: { // 顯示出來的頁數,如: 1 ... 34[5]67 ... 10 type: Number, default: 5 }, showPrev: { // 是否顯示「上一頁」 type: Boolean, default: true }, showNext: { // 是否顯示「下一頁」 type: Boolean, default: true }, showJump: { // 是否顯示「跳轉」 type: Boolean, default: true }, initPage: { type: Number, default: 1 } }, data () { return { currentPage: 0, pages: [], jumpPage: 0, } }, created () {// 初始化時currentPage賦值 this.currentPage = this.initPage } methods: { go (page) { if(page < 1) { page = 1 } if(page > this.totalPage) { page = this.totalPage } if(page === this.currentPage) { return } this.currentPage = parseInt(page,10) this.$emit('go-page',{ page: this.currentPage }) } }, watch: { currentPage (newVal) { this.jumpPage = newVal }, initPage (newVal) { if(this.currentPage !== newVal) { this.currentPage = newVal } } } } </script>
接下來就是pages
數組的值如何獲取到。因爲pages
始終是跟當前頁currentPage
以及配置中須要顯示的showItems
強相關的,那麼徹底能夠將pages
改成計算屬性:
computed: { pages () { // 根據起始頁碼和結束頁碼獲得頁碼數組 let getPages = (start,end) => { if(start <= 1 || start > end || start >= this.totalPage) { start = 2 } if(end >= this.totalPage || end < start || end <= 1) { end = this.totalPage - 1 } let arr = [] for(let i = start; i <= end; i++) { arr.push(i) } return arr } let counts = this.showItems if(this.totalPage < counts + 2) { return getPages(2,this.totalPage) } else { if(this.currentPage <= Math.ceil(counts/2)) { return getPages(2,counts) } else if(this.currentPage >= this.totalPage - Math.floor(counts/2)) { return getPages(this.totalPage + 1 - counts,this.totalPage - 1) } else { let half = Math.ceil(counts/2) - 1 let end = this.currentPage + half if(counts % 2 === 0) { end++ } return getPages(this.currentPage - half,end) } } } }
到這裏一個普通的翻頁組件基本上就實現了(樣式本身能夠去定製)。可是不少時候(特別是一些管理後臺),結合vue-router
作成SPA,一般會有這樣的需求:
翻到某個列表的某一頁以後,點擊某一項到編輯頁,編輯完成後但願可以返回到跳轉以前的那一頁。
這個需求若是僅僅用上面的pager
組件,實現起來就不是很方便。也許有人會說結合vuex
能夠,可是這樣的話須要在state中記錄下跳轉前的頁碼。假若有不少個翻頁列表,就須要記錄多個,這顯然並不優雅。
不過由於vue-router
實現的優雅,咱們要知足上面的需求也很簡單:
首先props上增長mode
配置,因爲當mode
爲params
時,跳轉須要知道是在哪個路由下,因此:
mode: { type: String, default: 'event' // 'event' | 'query' | 'params' }, routeName: { type: String }
而後再在實際跳轉的邏輯方法go(page)
裏面,作點更改:
go (page) { if(page < 1) { page = 1 } if(page > this.totalPage) { page = this.totalPage } if(page === this.currentPage) { return } this.currentPage = parseInt(page,10) if(this.mode == 'query') { let query = this.$route.query query.page = this.currentPage this.$router.go({query: query}) } else if(this.mode == 'params') { let params = this.$route.params params.page = this.currentPage this.$router.go({name: this.routeName,params: params}) } else { this.$emit('go-page',{ page: this.currentPage }) } }
這樣基本上就完成了一個簡單且通用的翻頁組件啦,接下里就是發不到倉庫裏供你們使用了。
本文最終實現的翻頁組件已經發布,你們能夠看一波源碼:
vue-simple-pager
整體上講的比較淺顯,但願能有幫助。