分享一下最近寫的前端分頁插件,分頁的基本需求都能滿足,上一頁,下一頁,跳頁,顯示條數等。頁面樣式是基於bootstrap4。因爲寫出來還沒經過深入的測試,難免會有些小問題,如若發現,請留言哦
首先在template引入pagination.js
<script type="application/javascript" src="../static/js/pagination.js"></script>
在子頁面調用
<div class="container-fluid">
<div class="container-fluid" style="text-align: right">
<button @click="addRole" style="width: 80px;" type="button" class="btn btn-sm btn-dark">新增角色</button>
</div>
<div style="padding: 8px 0" class="container-fluid">
<input @keyup.enter="search" v-model="searchVal.role" placeholder="角色名" type="text">
<select @change="search" v-model="searchVal.organizationType" style="height: 29px;margin-left: 10px">
<option value="">請選擇組織類型</option>
<option v-for="organization in organizationList" :value="organization.id">{[organization.name]}</option>
</select>
<button @click="search" style="margin-left: 50px;margin-top: -4px;width: 80px" type="button" class="btn btn-sm btn-dark">查詢</button>
<!--<button @click="exportAsExcel" style="margin-left: 10px;width: 80px;margin-top: -4px" type="button" class="btn btn-sm btn-secondary">導出Excel</button>-->
</div>
<table class="table table-sm table-striped" >
<thead>
<tr>
<th scope="col">所屬組織</th>
<th scope="col">角色名</th>
<th scope="col">類型</th>
<th scope="col">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(role,index) in roleList">
<td>{[role.organizationName]}</td>
<td>{[role.role]}</td>
<td>{[role.type]}</td>
<td>
<img @click="deleteRole(role.id)" style="width: 25px;height: 25px;cursor: pointer" src="../static/image/delete.svg">
<img @click="edit(role)" style="width: 25px;height: 23px;cursor: pointer" src="../static/image/edit.svg">
<img @click="permission(role.id)" style="width: 25px;height: 23px;cursor: pointer" src="../static/image/permission.svg">
</td>
</tr>
</tbody>
</table>
<-- 在tabel下使用分頁插件,插件會找到id生成對應的節點 -->
<div id="pagination"></div>
</div>
頁面效果是這樣的。如果是彈出層,則可惜選擇pagination-sm小規格的頁碼,註冊的時候添加。
這裏的上一頁和下一頁是從1-10 跳到 11-20 這種,固定10頁,也可以自行修改。不滿10頁超出的自動隱藏。
設計思路:
在點擊上一頁,下一頁,跳頁,指定頁,改變pageSize的時候,先處理active的頁碼。比如上一頁,下一頁只是將頁碼都+10,或者-10,之後在調用數據接口,取當前active的頁碼拉取數據。跳頁也是先處理跳到了哪個頁碼,將該頁碼active,在掉數據接口。總之,拉取數據都是在將頁碼active之後,然後根據$("#id .active")獲取是那頁,調數據接口。
js 中註冊:
mounted:function (){
var option = {
id:"#pagination",
url:'findRole',
size:"",//頁碼大小,大:pagination-lg,中:"",小:pagination-sm
isJump:true, //開啓跳頁
pageSize:10,
where:[],
callback:function (data) {
app.$data.roleList = data.results;
pageUtil.callBack(data)
}
};
pageUtil = $("#pagination").pagination(option);
},
上述中,where是用來傳入篩選條件的,跟後臺解析規則匹配,這一塊也可以跟着分頁封裝進去的,但是考慮簡單點,反正搜索的時候可以通過插件的返回體pageUtil進行操作。callBack是在插件將數據拉取後的回調函數。總的來說,在引用pagination.js之後只需要在頁面加<div id="id"> </div>,然後在頁面加載後註冊一下。因爲插件都是根據註冊的時候傳入的id來操作的,同時返回了一個pageUtil。每個pageUtil都是不一樣的,所以該分頁可以在一個頁面支持多個分頁,如彈出層,他們之間的分頁互不相干!
pagination.js:
function PageUtil(option) {
var util = {
id:option.id,
searchUrl:option.url,
pageSize:option.pageSize?option.pageSize:10,
pageTotal:option.pageTotal?option.pageTotal:1,
total:option.total?option.total:0,
where:option.where,
callback:option.callback,
isJump:option.isJump
};
function setPageSize(pageSize) {
util.pageSize = pageSize
}
function setWhere(where) {
util.where = where
}
return util
}
(function ($) {
$.fn.pagination = function (option) {
var pageUtil = new PageUtil(option);
var html = "";
html += '<ul style="float: left" class="pagination '+ option.size +'" ><li class="page-item"><a class="page-link" href="#">上一頁</a></li>';
for(var i = 1; i < 11; i++){
if(i === 1){
html += '<li class="page-item active"><a class="page-link" href="#">'+ i +'</a></li>';
}else {
html += '<li class="page-item "><a class="page-link" href="#">'+ i +'</a></li>';
}
}
html += '<li class="page-item "><a class="page-link" href="#">下一頁</a></li></ul>' ;
if(pageUtil.isJump){
var style = "pagination-jump";
option.size === "pagination-lg" && (style = "pagination-jump-lg");
option.size === "pagination-sm" && (style = "pagination-jump-sm");
html += '<div class="'+style+'" >\n' +
' <span style="margin-left: 10px">第</span>\n' +
' <input id="jumpPageIndex" type="text" >\n' +
' <span>頁</span>\n' +
' <button type="button" class="btn btn-dark btn-sm">跳轉</button>' +
'<label style="margin-left: 20px">每頁顯示條數</label><select class="form-control form-control-sm" style="margin-left: 10px;width: 80px;display: inline">' +
' <option value=10>10</option>' +
' <option value=20>20</option>' +
' <option value=30>30</option>' +
' <option value=50>50</option>' +
' <option value=100>100</option>' +
'</select>' +
' <span style="margin-left: 20px">共 <span class="page_total">'+pageUtil.pageTotal+' </span>頁/<span class="total_number"> '+pageUtil.total+'</span>條</span>' +
'</div>'
}
$(pageUtil.id).html(html);
$(pageUtil.id).find("li").each(function () {
$(this).click(function () {
if(this.innerText.indexOf("上一頁") !== -1 ){ //不知爲何此處的innerText會變成“上一頁/回車”,等號驗證不了
lastPage(pageUtil)
}else if(this.innerText.indexOf("下一頁") !== -1 ){
nextPage(pageUtil)
}else{
currentPage(pageUtil,this.innerText)
}
})
});
//給跳頁綁定事件
$(pageUtil.id).find("button")[0].onclick = function () {
if(pageUtil.pageTotal - $(pageUtil.id + " input").val() >= 0){
//先將頁面跳到指定頁數
jumpPage(pageUtil,$(pageUtil.id + " input").val());
loadData(pageUtil);
}
};
//給選擇每頁顯示條數綁定change事件
$(pageUtil.id).find("select")[0].onchange = function () {
if(pageUtil.pageSize !== $(pageUtil.id + " select").val()){
pageUtil.pageSize = $(pageUtil.id + " select").val();
loadData(pageUtil)
}
};
//加載第一頁數據
loadData(pageUtil);
return {
util:pageUtil,
reload:loadData,
callBack:function (data) {
pageUtil.pageTotal = data.totalPage;
pageUtil.total = data.total;
$(pageUtil.id + " .page_total").text(pageUtil.pageTotal);
$(pageUtil.id + " .total_number").text(pageUtil.total);
//重新顯示頁碼
changeShowPage(pageUtil)
}
}
};
//url,pageUtil
function loadData (util,object){
if(object){
//如果object是數組,則是搜索
if(object.constructor === Array){
util.where = object;
bee.getWithLoading(util.searchUrl,{pageNum:1,pageSize:util.pageSize,where:JSON.stringify(util.where)},util.callback);
$(util.id + " .active").removeClass("active");
$($(util.id + " li")[1]).addClass("active");
}
//如果object是function
if(typeof object === "function"){
bee.get(util.searchUrl,{pageNum:$(util.id + " .active").text(),pageSize:util.pageSize,where:JSON.stringify(util.where)},object);
}
}else {
bee.getWithLoading(util.searchUrl,{pageNum:$(util.id + " .active").text(),pageSize:util.pageSize,where:JSON.stringify(util.where)},util.callback);
}
//默認情況
}
function lastPage(util) {
changePageNum(true,util);
}
function nextPage(util) {
changePageNum(false,util)
}
function currentPage(util,pageIndex) {
$(util.id).find("li").each(function () {
this.innerText !== pageIndex ? $(this).removeClass("active") : $(this).addClass("active")
});
loadData(util)
}
function changePageNum(isLast,util) {
if((isLast && $(util.id + " li").find("a")[1].innerText - 10 > 0) || (!isLast && pageTotal - $(util.id + " li").find("a")[1].innerText >= 10)){
$(util.id +" li").find("a").each(function () {
this.innerText.indexOf("一頁") === -1 && (isLast?this.innerText -= util.pageSize:this.innerText -= -util.pageSize);
});
loadData(util)
}
changeShowPage(util)
}
function changeShowPage(util) {
$(util.id).find("li").each(function () {
this.innerText - util.pageTotal > 0 ? this.style.display = "none" : this.style.display = "inline"
})
}
function jumpPage(util,pageIndex) {
var num = Math.ceil(pageIndex/10);
for(var i = 0 ;i < 10 ; i++){
$(util.id + " a")[i+1].innerText = ((num-1)*10 + i + 1);
if(pageIndex - (num-1)*10 - i - 1 === 0 ){
$(util.id + " .active").removeClass("active");
$($(util.id + " li")[i+1]).addClass("active");
}
}
changeShowPage(util)
}
})(jQuery);
在上面代碼中加載數據都會有loading出現,loading在temlate裏。請求分2種形式,getWithLoading會改變tempalte的loading的顯示隱藏
getWithLoading:function(url,params,callback,error,async){
$("#loading")[0].style.display = "block";
var option = {
url:url,
data:params,
type:"get",
async:async,
dataType:"json",
success:function (data) {
$("#loading")[0].style.display = "none";
callback(data)
},
error:error?error:function () {
$("#loading")[0].style.display = "none";
alert("發生錯誤,請聯繫管理員")
}
};
$.ajax(option)
},
<!-- loading-->
<div style="width: 100%;height: 100%;background-color: #5e5e5e;position: absolute;z-index: 99999;opacity: 0.3;display: none" id="loading">
<div style="width: 200px;height: 50px;position: absolute;top: 40%;left: 40% ">
<img src="../static/image/loading.gif">
<span style="color: white">正在請求數據......</span>
</div>
</div>
css部分:
/* 分頁大中小樣式 */
.pagination-jump {
float: left;
margin-left: 15px;
padding-top: 4px;
font-size: 14px;
}
.pagination-jump input{
width: 40px;
height: 20px;
}
.pagination-jump button{
line-height: 1.2;
font-size: 0.75rem;
margin-left: 10px
}
.pagination-jump-lg {
float: left;
margin-left: 20px;
padding-top: 10px
}
.pagination-jump-lg input{
width: 50px;
height: 30px;
}
.pagination-jump-sm {
float: left;
margin-left: 10px;
font-size: 12px;
}
.pagination-jump-sm input {
width: 30px;
height: 18px;
}
.pagination-jump-sm button {
line-height: 1;
font-size: 0.7rem;
margin-left: 10px
}