Vue組件實戰(zhàn):分頁組件開發(fā)
介紹
在Web應(yīng)用程序中,分頁功能是必不可少的一個組件。一個好的分頁組件應(yīng)該展示簡潔明了,功能豐富,而且易于集成和使用。
在本文中,我們將介紹如何使用Vue.js框架來開發(fā)一個高度可定制化的分頁組件。我們將通過代碼示例來詳細說明如何使用Vue組件開發(fā)。
技術(shù)棧
Vue.js 2.xJavaScript (ES6)HTML5和CSS3
開發(fā)環(huán)境
Node.js v8.9.3npm v5.5.1Vue.js v2.5.2
分頁組件需求
通過props接收總頁面數(shù)(total)和當前頁面數(shù)(current)屬性可以配置顯示的最大頁碼數(shù)(maxShown)可以配置按鈕顯示的文本 (prevText和nextText) 和按鈕樣式點擊頁碼可以切換到相應(yīng)的頁面當前頁碼高亮顯示當前頁面沒有前一頁時,忽略上一頁按鈕的點擊事件當前頁面沒有后一頁時,忽略下一頁按鈕的點擊事件
設(shè)計思路和代碼實現(xiàn)
根據(jù)需求,我們將分頁組件拆分為多個小組件來實現(xiàn)。我們需要創(chuàng)建以下3個小組件:
- Pagination.vue
主分頁組件,負責分頁數(shù)據(jù)和邏輯的處理。向子組件傳遞分頁信息和響應(yīng)子組件的事件。
- Button.vue
該組件為按鈕組件,用于創(chuàng)建分頁按鈕。
- Page.vue
該組件用于創(chuàng)建單個頁面塊,包含頁面標號和狀態(tài)。頁面塊可以是當前頁面或非當前頁面。
接下來,讓我們使用代碼來實現(xiàn)以上3個組件。
- Pagination.vue
<template>
<div class="pagination-container">
<button-prev :current="current" @onPrev="prev"></button-prev>
<page v-for="page in pages"
:key="page"
:page="page"
:is-selected="page === current"
@on-page-selected="selectPage"></page>
<button-next :current="current" :total="total" @onNext="next"></button-next>
</div>
</template>
<script>
import ButtonPrev from './ButtonPrev.vue';
import ButtonNext from './ButtonNext.vue';
import Page from './Page.vue';
export default {
components: { ButtonPrev, ButtonNext, Page },
props: {
total: {
type: Number,
default: 10
},
current: {
type: Number,
default: 1
},
maxShown: {
type: Number,
default: 5
},
prevText: {
type: String,
default: '上一頁'
},
nextText: {
type: String,
default: '下一頁'
}
},
computed: {
pages () {
const start = Math.max(1, this.current - Math.floor(this.maxShown / 2));
const end = Math.min(this.total, start + this.maxShown - 1);
return Array.from({ length: end - start + 1 }, (v, k) => start + k);
}
},
methods: {
selectPage (page) {
if (this.current === page) return;
this.current = page;
this.$emit('onPageChanged', page);
},
prev () {
if (this.current > 1) {
this.selectPage(this.current - 1);
}
},
next () {
if (this.current < this.total) {
this.selectPage(this.current + 1);
}
}
}
}
</script>
登錄后復制
上面的代碼中,我們首先import了ButtonPrev、ButtonNext和Page組件。接著,用props方式獲取了total, current, maxShown, prevText和nextText屬性,并定義了計算屬性pages,根據(jù)當前頁碼(current)和最大頁碼數(shù)(maxShown)得到一個包含頁碼數(shù)的數(shù)組,以在組件中呈現(xiàn)。
我們還定義了selectPage方法,在該方法中,如果頁碼(page)與當前頁碼(current)相同,則返回或不做任何事情。否則,將新頁碼發(fā)出給父組件。
prev()和next()方法用于處理上一頁和下一頁事件,并防止event被響應(yīng)。
- ButtonPrev.vue
<template>
<button
class="btn-previous"
:disabled="current === 1"
@click="onPrev()">
{{ prevText }}
</button>
</template>
<script>
export default {
props: {
prevText: {
type: String,
default: '上一頁'
},
current: {
type: Number,
default: 1
}
},
methods: {
onPrev () {
this.$emit('onPrev');
}
}
}
</script>
<style scoped>
.btn-previous {
border: none;
color: #333;
display: inline-block;
font-size: 16px;
padding: 6px 12px;
margin-right: 5px;
background-color:#fff;
cursor: pointer;
border-radius: 2px;
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
}
.btn-previous:disabled {
color: #ccc;
cursor: default;
}
</style>
登錄后復制
上述代碼中,我們首先通過props獲取了當前頁碼(current)和上一頁按鈕的文本(prevText)屬性。在模版中,使用類綁定(disabled)控制按鈕使用狀態(tài)。定義了一個onPrev方法,該方法觸發(fā)父組件的onPrev事件。
- ButtonNext.vue
<template>
<button
class="btn-next"
:disabled="current === total"
@click="onNext()">
{{ nextText }}
</button>
</template>
<script>
export default {
props: {
total: {
type: Number,
default: 10
},
nextText: {
type: String,
default: '下一頁'
},
current: {
type: Number,
default: 1
}
},
methods: {
onNext () {
this.$emit('onNext');
}
}
}
</script>
<style scoped>
.btn-next {
border: none;
color: #333;
display: inline-block;
font-size: 16px;
padding: 6px 12px;
margin-left: 5px;
background-color: #fff;
cursor: pointer;
border-radius: 2px;
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
}
.btn-next:disabled {
color: #ccc;
cursor: default;
}
</style>
登錄后復制
上述代碼中,我們將ButtonPrev.vue的代碼復制了一份,稍微改了一下文本和判斷條件。
- Page.vue
<template>
<button :class="{ current: isSelected }" class="btn-page" @click="onPageSelected(page)">
{{ page }}
</button>
</template>
<script>
export default {
props: {
page: {
type: Number,
required: true
},
isSelected: {
type: Boolean,
default: false
}
},
methods: {
onPageSelected () {
this.$emit('onPageSelected', this.page);
}
}
}
</script>
<style scoped>
.btn-page {
border: none;
color: #333;
display: inline-block;
font-size: 16px;
padding: 6px 12px;
margin-left: 5px;
background-color: #fff;
cursor: pointer;
border-radius: 2px;
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
}
.btn-page.current {
background-color: #0078d7;
color: #fff;
}
</style>
登錄后復制
上述代碼中,我們通過props獲取了該頁碼的值(page)和按鈕的isSelected屬性。在模板中,使用類綁定(“current”)高亮顯示選中的頁面。
我們還定義了一個onPageSelected方法,該方法會觸發(fā)父組件的onPageSelected事件。
最后,這些組件可以在任何Vue.js應(yīng)用程序中的template中使用,如下所示:
<template>
<div>
<pagination
:total="total"
:current="current"
:maxShown="maxShown"
:prevText="prevText"
:nextText="nextText"
@onPageChanged="onPageChanged"></pagination>
<ul>
<li v-for="(item, index) in items" :key="index">{{ item.name }}</li>
</ul>
</div>
</template>
<script>
import Pagination from './Pagination.vue';
export default {
components: {
Pagination
},
data () {
return {
current: 1,
maxShown: 10,
prevText: '上一頁',
nextText: '下一頁',
total: 10,
pageSize: 10,
items: [{ name: 'Item 1' }, { name: 'Item 2' }, { name: 'Item 3' }]
}
},
methods: {
onPageChanged (page) {
console.log('Page changed to: ', page);
// 當前頁面數(shù)據(jù)請求
}
}
}
</script>
登錄后復制
上述代碼中,我們引入了Pagination組件,并將其作為template中的父組件。我們還將total, current和maxShown綁定到組件,以便獲取到它們的值。在onPageChanged方法中,我們可以處理頁面更改事件,并根據(jù)當前頁碼請求相應(yīng)的數(shù)據(jù)。






