這次帶給大家Vue建構分頁元件步驟詳解,Vue建構分頁元件的注意事項有哪些,以下就是實戰案例,一起來看一下。
Web應用程式中資源分頁不僅對效能很有幫助,而且從使用者體驗的角度來說也是非常有用的。在這篇文章中,將了解如何使用Vue建立動態和可用的分頁元件。
基本結構
分頁元件應該允許使用者訪問第一個和最後一個頁面,向前和向後移動,並直接切換到近距離的頁面。
大多數應用程式在使用者每次變更頁面時都會發出API請求。我們需要確保元件允許這樣做,但是我們不希望在元件內發出這樣的請求。這樣,我們將確保元件在整個應用程式中是可重複使用的,並且請求都是在操作或服務層中進行的。我們可以透過使用使用者點擊的頁面的數字觸發事件來實現此目的。
有幾種可能的方法來實作API端點上的分頁。對於這個例子,我們假設API告訴我們每個頁面的結果數量、頁面總數和目前頁面。這些將會是我們的動態 props 。
相反,如果API只告訴記錄的總數,那麼我們可以透過將結果的數量除以每一頁的結果數來計算頁數: totalResults / resultsPerPage 。
我們想要渲染一個按鈕到第一頁、 上一頁、 頁面數量範圍、 下一頁和最後一頁:
[first] [next] [1] [2 ] [3] [previous] [last]
例如像下圖這樣的一個效果:
儘管我們希望渲染一個系列的頁面,但並不希望渲染所有可用頁面。讓我們允許在我們的元件中設定一個最多可見按鈕的 props 。
既然我們知道了我們想要的元件要做成什麼,需要哪些數據,我們就可以設定HTML結構和所需的 props 。
<template id="pagination"> <ul class="pagination"> <li> <button type="button">« First</button> </li> <li> <button type="button">«</button> </li> <!-- 页数的范围 --> <li> <button type="button">Next »</button> </li> <li> <button type="button">»</button> </li> </ul> </template> Vue.component('pagination', { template: '#pagination', props: { maxVisibleButtons: { type: Number, required: false, default: 3 }, totalPages: { type: Number, required: true }, total: { type: Number, required: true }, currentPage: { type: Number, required: true } } })
上面的程式碼註冊了一個pagination 元件,如果呼叫這個元件:
<p id="app"> <pagination></pagination> </p>
這個時候看到的效果如下:
#注意,為了能讓元件看起來好看一點,為元件添加了一點樣式。
事件監聽
現在我們需要通知父元件,當使用者點擊按鈕時,使用者點擊了哪個按鈕。
我們需要為每個按鈕新增一個事件監聽器。 v-on 指令 允許偵聽DOM事件。在本例中,我將使用 v-on 的快捷鍵 來偵聽單擊事件。
為了通知父節點,我們將使用 $emit 方法 來發出一個帶有頁面點擊的事件。
我們也要確保分頁按鈕只有在頁面可用時才唯一一個目前狀態。為了這樣做,將使用 v-bind 將 disabled 屬性的值與目前頁面綁定。我們還是使用 :v-bind 的快捷鍵 : 。
為了保持我們的 template 乾淨,將使用 computed 屬性 來檢查按鈕是否已停用。使用 computed 也會被緩存,這意味著只要 currentPage 不會更改,對相同計算屬性的幾個訪問將返回先前計算的結果,而不必再次運行該函數。
<template id="pagination"> <ul class="pagination"> <li> <button type="button" @click="onClickFirstPage" :disabled="isInFirstPage">« First</button> </li> <li> <button type="button" @click="onClickPreviousPage" :disabled="isInFirstPage">«</button> </li> <li v-for="page in pages"> <button type="button" @click="onClickPage(page.name)" :disabled="page.isDisabled"> {{ page.name }}</button> </li> <li> <button type="button" @click="onClickNextPage" :disabled="isInLastPage">Next »</button> </li> <li> <button type="button" @click="onClickLastPage" :disabled="isInLastPage">»</button> </li> </ul> </template> Vue.component('pagination', { template: '#pagination', props: { maxVisibleButtons: { type: Number, required: false, default: 3 }, totalPages: { type: Number, required: true }, total: { type: Number, required: true }, currentPage: { type: Number, required: true } }, computed: { isInFirstPage: function () { return this.currentPage === 1 }, isInLastPage: function () { return this.currentPage === this.totalPages } }, methods: { onClickFirstPage: function () { this.$emit('pagechanged', 1) }, onClickPreviousPage: function () { this.$emit('pagechanged', this.currentPage - 1) }, onClickPage: function (page) { this.$emit('pagechanged', page) }, onClickNextPage: function () { this.$emit('pagechanged', this.currentPage + 1) }, onClickLastPage: function () { this.$emit('pagechanged', this.totalPages) } } })
在呼叫pagination 元件時,將totalPages 和total 以及currentPage 傳到元件中:
<p id="app"> <pagination :total-pages="11" :total="120" :current-page="currentPage"></pagination> </p> let app = new Vue({ el: '#app', data () { return { currentPage: 2 } } })
執行上面的程式碼,將會報錯:
##
不難發現,在pagination 元件中,咱們還少了pages 。從前面介紹的內容,我們不難發現,需要計算 pages 的值。Vue.component('pagination', { template: '#pagination', props: { maxVisibleButtons: { type: Number, required: false, default: 3 }, totalPages: { type: Number, required: true }, total: { type: Number, required: true }, currentPage: { type: Number, required: true } }, computed: { isInFirstPage: function () { return this.currentPage === 1 }, isInLastPage: function () { return this.currentPage === this.totalPages }, startPage: function () { if (this.currentPage === 1) { return 1 } if (this.currentPage === this.totalPages) { return this.totalPages - this.maxVisibleButtons + 1 } return this.currentPage - 1 }, endPage: function () { return Math.min(this.startPage + this.maxVisibleButtons - 1, this.totalPages) }, pages: function () { const range = [] for (let i = this.startPage; i <= this.endPage; i+=1) { range.push({ name: i, isDisabled: i === this.currentPage }) } return range } }, methods: { onClickFirstPage: function () { this.$emit('pagechanged', 1) }, onClickPreviousPage: function () { this.$emit('pagechanged', this.currentPage - 1) }, onClickPage: function (page) { this.$emit('pagechanged', page) }, onClickNextPage: function () { this.$emit('pagechanged', this.currentPage + 1) }, onClickLastPage: function () { this.$emit('pagechanged', this.totalPages) } } })
新增樣式 现在我们的组件实现了最初想要的所有功能,而且添加了一些样式,让它看起来更像一个分页组件,而不仅像是一个列表。 我们还希望用户能够清楚地识别他们所在的页面。让我们改变表示当前页面的按钮的颜色。 为此,我们可以使用对象语法将HTML类绑定到当前页面按钮上。当使用对象语法绑定类名时,Vue将在值发生变化时自动切换类。 虽然 v-for 中的每个块都可以访问父作用域范围,但是我们将使用 method 来检查页面是否处于 active 状态,以便保持我们的 templage 干净。 接下来,在 pages 中添加当前状态: 这个时候你看到效果如下: 但依然还存在一点点小问题,当你在点击别的按钮时, active 状态并不会随着切换: 继续添加代码改变其中的效果: 在调用组件时: 这个时候的效果如下了: 到这里,基本上实现了咱想要的分页组件效果。 无障碍化处理 熟悉Bootstrap的同学都应该知道,Bootstrap中的组件都做了无障碍化的处理,就是在组件中添加了WAI-ARIA相关的设计。比如在分页按钮上添加 aria-label 相关属性: 在我们这个组件中,也相应的添加有关于WAI-ARIA相关的处理: 这样有关于 aria 相关的属性就加上了: 相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章! 推荐阅读:Vue.component('pagination', {
template: '#pagination',
props: {
maxVisibleButtons: {
type: Number,
required: false,
default: 3
},
totalPages: {
type: Number,
required: true
},
total: {
type: Number,
required: true
},
currentPage: {
type: Number,
required: true
}
},
computed: {
isInFirstPage: function () {
return this.currentPage === 1
},
isInLastPage: function () {
return this.currentPage === this.totalPages
},
startPage: function () {
if (this.currentPage === 1) {
return 1
}
if (this.currentPage === this.totalPages) {
return this.totalPages - this.maxVisibleButtons + 1
}
return this.currentPage - 1
},
endPage: function () {
return Math.min(this.startPage + this.maxVisibleButtons - 1, this.totalPages)
},
pages: function () {
const range = []
for (let i = this.startPage; i <= this.endPage; i+=1) {
range.push({
name: i,
isDisabled: i === this.currentPage
})
}
return range
}
},
methods: {
onClickFirstPage: function () {
this.$emit('pagechanged', 1)
},
onClickPreviousPage: function () {
this.$emit('pagechanged', this.currentPage - 1)
},
onClickPage: function (page) {
this.$emit('pagechanged', page)
},
onClickNextPage: function () {
this.$emit('pagechanged', this.currentPage + 1)
},
onClickLastPage: function () {
this.$emit('pagechanged', this.totalPages)
},
isPageActive: function (page) {
return this.currentPage === page;
}
}
})
<li v-for="page in pages">
<button type="button" @click="onClickPage(page.name)" :disabled="page.isDisabled" :class="{active: isPageActive(page.name)}"> {{ page.name }}</button>
</li>
let app = new Vue({
el: '#app',
data () {
return {
currentPage: 2
}
},
methods: {
onPageChange: function (page) {
console.log(page)
this.currentPage = page;
}
}
})
<p id="app">
<pagination :total-pages="11" :total="120" :current-page="currentPage" @pagechanged="onPageChange"></pagination>
</p>
<template id="pagination">
<ul class="pagination" aria-label="Page navigation">
<li>
<button type="button" @click="onClickFirstPage" :disabled="isInFirstPage" aria-label="Go to the first page">« First</button>
</li>
<li>
<button type="button" @click="onClickPreviousPage" :disabled="isInFirstPage" aria-label="Previous">«</button>
</li>
<li v-for="page in pages">
<button type="button" @click="onClickPage(page.name)" :disabled="page.isDisabled" :aria-label="`Go to page number ${page.name}`"> {{ page.name }}</button>
</li>
<li>
<button type="button" @click="onClickNextPage" :disabled="isInLastPage" aria-label="Next">Next »</button>
</li>
<li>
<button type="button" @click="onClickLastPage" :disabled="isInLastPage" aria-label="Go to the last page">»</button>
</li>
</ul>
</template>
以上是Vue建置分頁組件步驟詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!