vue bootstrap有一个很强大的组件bootstrap-vue。但是这个组件的分页貌似并不支持前后端分离的分页。
我至少是没看出来。如果有看出来的请告诉我。
如果有用这个组件的同学可以跟我交流。
QQ:871966163
直通车bootstrap-vue
自己写了个分页组件,开箱即用。如有bug欢迎留言。
嫌麻烦大佬可以直通github,clone项目直接使用
vue-bootstrap-pagination
另外封装了一个 渲染函数&jsx的分页组件,有需要可以加QQ交流
1、 参数
(1)props参数
total:数据总数,这个是必传参数。比如总数据有1000条,10000条。 数量为0,负数或者非数字字符串时,total取值为1,也就是最小值为1
size: 每一页的数据条数。比如每一页显示10条,15条。 数字为0,负数或者非数字字符串时,size取值为10
currentPage:分页初始页码,就是第一次进入有分页的这个页面显示的页码。记住是第一次。数字为0,附属或者为非数字字符串时,currentPage取值为1,也就是最小值为1
这个数据是可以在操作分页的时候修改的,方便 vuex 记住当前页面,然后赋值初始页面,实现在第 N 页查看某一条数据进入另一个页面回来时还是会停留在第 N 页的效果,或者看到第 N 页了,点击其他页面,再点击回来,仍然会停留在第 N 页。
这个功能需要配合
- limit:分页元素。分页条显示的元素数量。数字小于5或者为非数字字符串时,limit取值为5,也就是最小值为5
比如limit=5,会显示如下:
也就是除了左右两边箭头按钮会显示的分页元素数量
-
:分页位置, left:左边,center:居中, right:右边。默认在左边
align=center
align=right
firstFunction:点击跳转到第一页触发函数
prevFunction:上一页按钮触发函数
currentFunction:点击页码触发函数
nextFunction:下一页按钮触发函数
lastFunction:最后一页按钮触发函数
sizeFunction:改变每页数量触发函数
props: {
//总数据
total: {
type: [Number, String],
required: true
},
// 每页数量
size: {
type: [Number, String],
default: 10
},
// 初始页码
currentPage: {
type: [Number, String],
default: 1
},
// 分页显示数量
limit: {
type: [Number, String],
default: 5
},
// 分页位置
align: {
default: "left",
type: String
},
// 跳转第一页按钮触发函数
firstFunction: {
type: Function,
required: true
},
// 上一页按钮触发函数
prevFunction: {
type: Function,
required: true
},
// 点击页码触发函数
currentFunction: {
type: Function,
required: true
},
// 下一页按钮触发函数
nextFunction: {
type: Function,
required: true
},
// 最后一页按钮触发函数
lastFunction: {
type: Function,
required: true
},
// 修改每页数量触发函数
sizeFunction: {
type: Function
}
},
(2)data参数
- tempalteCurrentPage:分页当前页码。也就是激活的页码
data() {
return {
tempalteCurrentPage: ""
};
},
2、 方法methods
- toInteger:字符串转为数字类型
- _firstFunction:跳转第一页按钮触发函数
- _prevFunction:上一页按钮触发函数
- _currentFunction:点击页码触发函数
- _nextFunction:下一页按钮触发函数
- _lastFunction:最后一页按钮触发函数
- _sizeFunction:修改每页数量触发函数
methods: {
// 字符串转为数字类型 因为props会接收字符串,所以需要进行转换
toInteger(val) {
return parseInt(val, 10);
},
// 跳转第一页按钮触发函数
_firstFunction() {
if (this.firstFunction) {
this.tempalteCurrentPage = 1;
this.firstFunction();
}
},
// 上一页按钮触发函数
_prevFunction() {
if (this.prevFunction) {
this.tempalteCurrentPage = this.tempalteCurrentPage - 1;
this.prevFunction();
}
},
// 点击页码触发函数
_currentFunction(item) {
if (this.currentFunction) {
this.tempalteCurrentPage = item;
this.currentFunction();
}
},
// 下一页按钮触发函数
_nextFunction() {
if (this.nextFunction) {
this.tempalteCurrentPage = this.tempalteCurrentPage + 1;
this.nextFunction();
}
},
// 最后一页按钮触发函数
_lastFunction() {
if (this.lastFunction) {
this.tempalteCurrentPage = this.nlyPgPages;
this.lastFunction();
}
},
// 修改每页数量触发函数
_sizeFunction() {
if (this.sizeFunction) {
this.sizeFunction();
}
},
// 分页元素添加上一页,最后一页,第一页,下一页等按钮
_tempalteArray() {
// this.nlyPgItemArray为 computed 中 nlyPgItemArray属性
let nlyPgItemArrayAll = this.nlyPgItemArray;
nlyPgItemArrayAll.splice(0, 0, "‹");
nlyPgItemArrayAll.splice(0, 0, "‹‹");
nlyPgItemArrayAll.push("›");
nlyPgItemArrayAll.push("››");
return nlyPgItemArrayAll;
}
},
3、 计算属性computed
- nlyPgTotal:转换总页转为数字类型
- nlyPgSize:每页数量转为数字类型
- nlyPgCurrentPage:当前页数转为数字类型
- nlyPgLimit:分页显示元素转为数字类型
- nlyPgPages:计算总页数
- nlyPgItemArray: 生成不包括上一页,下一页等按钮的分页元素
- alignClass:分页位置
- tempalteArray:生成包括最后一页,上一页,第一页,下一页等按钮的元素,最终分页元素
computed: {
// 转换总页转为数字类型
nlyPgTotal: function() {
return isNaN(this.toInteger(this.total))
? 1
: this.toInteger(this.total) <= 0
? 1
: this.toInteger(this.total);
},
// 每页数量转为数字类型
nlyPgSize: function() {
return isNaN(this.toInteger(this.size))
? 10
: this.toInteger(this.size) <= 0
? 10
: this.toInteger(this.size);
},
// 当前页数转为数字类型
nlyPgCurrentPage: function() {
return this.toInteger(this.tempalteCurrentPage);
},
// 分页显示元素转为数字类型
nlyPgLimit: function() {
return isNaN(this.toInteger(this.limit))
? 5
: this.toInteger(this.limit) <= 4
? 5
: this.toInteger(this.limit);
},
// 计算总页数
nlyPgPages: function() {
return Math.ceil(this.nlyPgTotal / this.nlyPgSize);
},
// 生成不包括上一页,下一页等按钮的分页元素
nlyPgItemArray: function() {
if (
this.nlyPgCurrentPage + 1 <= this.nlyPgLimit &&
this.nlyPgPages < this.nlyPgLimit
) {
// 当前页码+1小于分页元素且总页数大于分页元素
const itemList = Array.from({ length: this.nlyPgPages }).map(
(v, k) => k + 1
);
return itemList;
} else if (
this.nlyPgCurrentPage + 1 <= this.nlyPgLimit &&
this.nlyPgPages == this.nlyPgLimit
) {
// 当前页码+1小于分页元素且总页数等于分页元素
const itemList = Array.from({ length: this.nlyPgLimit }).map(
(v, k) => k + 1
);
return itemList;
} else if (
this.nlyPgCurrentPage + 2 <= this.nlyPgLimit &&
this.nlyPgPages > this.nlyPgLimit
) {
// 当前页码+2小于分页元素且总页数大于分页元素
const itemList = Array.from({ length: this.nlyPgLimit - 1 }).map(
(v, k) => k + 1
);
itemList.push("···");
return itemList;
} else if (
this.nlyPgPages - this.nlyPgCurrentPage + 2 < this.nlyPgLimit &&
this.nlyPgPages > this.nlyPgLimit
) {
// 总页数-当前页码+2小于分页元素且总页数大于分页元素
const itemList = Array.from({ length: this.nlyPgLimit - 1 }).map(
(v, k) => k + (this.nlyPgPages - this.nlyPgLimit + 2)
);
itemList.splice(0, 0, "···");
return itemList;
} else if (
// 总页数-当前页码+2小于分页元素且总页数等于分页元素
this.nlyPgPages - this.nlyPgCurrentPage + 2 < this.nlyPgLimit &&
this.nlyPgPages == this.nlyPgLimit
) {
const itemList = Array.from({ length: this.nlyPgLimit - 1 }).map(
(v, k) => k + (this.nlyPgPages - this.nlyPgLimit + 2)
);
return itemList;
} else {
// 其他情况
const itemList = Array.from({ length: this.nlyPgLimit - 2 }).map(
(v, k) =>
k + this.nlyPgCurrentPage - Math.ceil(this.nlyPgLimit / 2) + 2
);
itemList.splice(0, 0, "···");
itemList.push("···");
return itemList;
}
},
// 分页位置
alignClass: function() {
const align = this.align;
if (align === "center") {
return "justify-content-center";
} else if (align === "end" || align === "right") {
return "justify-content-end";
}
return "";
},
// 生成包括最后一页,上一页,第一页,下一页等按钮的元素,最终分页元素
tempalteArray: function() {
return this._tempalteArray();
}
},
4、 页面渲染created生命周期
created() {
// 初始化初始页面
this.tempalteCurrentPage = isNaN(this.toInteger(this.currentPage))
? 1
: this.toInteger(this.currentPage) <= 1
? 1
: this.toInteger(this.currentPage);
},
5、 页面监控watch
watch: {
// 暴露当前页码给父组件(变化之前的,如果从第4页跳转到第5页,父组件获取的值是4)
tempalteCurrentPage: function() {
this.$emit("getCurrentPage", this.tempalteCurrentPage);
},
// 监测父组件传入的初始页码currentPage,发生变化就给分页当前页码赋值
currentPage: function(newval, oldval) {
if (newval != oldval) {
this.tempalteCurrentPage = this.toInteger(this.currentPage);
}
},
// 监测总页数,当页数(即总数量发生变化的时候),如果当前页码大于总页数,当前页码变为最大页面,否则不变,
nlyPgPages: function(newval, oldval) {
if (newval != oldval) {
this.tempalteCurrentPage =
this.tempalteCurrentPage > newval ? newval : this.tempalteCurrentPage;
}
},
// 监测每页数量变化,发生变化的时候,重新执行_sizeFunction(),不传入组件参数sizeFunction也会执行。
nlyPgSize: function(newval, oldval) {
if (newval != oldval) {
this._sizeFunction();
}
}
}
6、 css
<style>
.nly-pagination-item {
cursor: pointer;
color: #007bff;
}
</style>
7、 template
<template>
<ul :class="'pagination ' + alignClass">
<template v-for="(item, index) in tempalteArray">
<!-- 跳转第一页按钮 -->
<template v-if="item == '‹‹'">
<!-- 当前页面为第一页的时候禁用 -->
<li
class="page-item disabled"
:key="index"
v-if="nlyPgCurrentPage == 1"
>
<a class="page-link"> {{ item }}</a>
</li>
<!-- 当前页面不为第一页的时候 -->
<li
class="page-item nly-pagination-item"
:key="index"
v-else
@click="_firstFunction"
>
<a class="page-link"> {{ item }}</a>
</li>
</template>
<!-- 上一页按钮 -->
<template v-else-if="item == '‹'">
<!-- 当前页面为第一页的时候禁用 -->
<li
class="page-item disabled"
:key="index"
v-if="nlyPgCurrentPage == 1"
>
<a class="page-link"> {{ item }}</a>
</li>
<!-- 当前页面不为第一页的时候 -->
<li
class="page-item nly-pagination-item"
:key="index"
v-else
@click="_prevFunction"
>
<a class="page-link"> {{ item }}</a>
</li>
</template>
<!-- 省略按钮 禁用 -->
<template v-else-if="item == '···'">
<li class="page-item disabled" :key="index">
<a class="page-link"> {{ item }}</a>
</li>
</template>
<!-- 跳转到最后一页按钮 -->
<template v-else-if="item == '››'">
<!-- 当前页面为最后一页的时候禁用 -->
<li
class="page-item disabled"
:key="index"
v-if="nlyPgCurrentPage == nlyPgPages"
>
<a class="page-link"> {{ item }}</a>
</li>
<!-- 当前页面不为最后一页的时候 -->
<li
class="page-item nly-pagination-item"
:key="index"
v-else
@click="_lastFunction"
>
<a class="page-link"> {{ item }}</a>
</li>
</template>
<!-- 下一页按钮 -->
<template v-else-if="item == '›'">
<!-- 当前页面为最后一页的时候禁用 -->
<li
class="page-item disabled"
:key="index"
v-if="nlyPgCurrentPage == nlyPgPages"
>
<a class="page-link"> {{ item }}</a>
</li>
<!-- 当前页面不为最后一页的时候 -->
<li
class="page-item nly-pagination-item"
:key="index"
v-else
@click="_nextFunction"
>
<a class="page-link"> {{ item }}</a>
</li>
</template>
<!-- 当前页码激活状态 -->
<template v-else-if="item == tempalteCurrentPage">
<li
class="page-item active nly-pagination-item"
:key="index"
@click="_currentFunction(item)"
>
<a class="page-link"> {{ item }}</a>
</li>
</template>
<!-- 点击跳转页码 -->
<template v-else>
<li
class="page-item nly-pagination-item"
:key="index"
@click="_currentFunction(item)"
>
<a class="page-link"> {{ item }}</a>
</li>
</template>
</template>
</ul>
</template>
8、 组件
-
1 新建一个vue项目,过程省略。这里用的vue cli3以上版本。
目录如下
-
2 在components下建立一个NLYpagination.vue和index.js
vue文件名字随意,index最好不改,如果改了在接下来的main.js引入的时候也有改。
把上面的代码放到NLYpagination.vue中。
- 注册组件
打开刚刚建立的index.js,写入以下代码。注意import路径
import NLYpagination from "../components/NLYpagination.vue";
export default {
install: Vue => {
Vue.component("NLY-pagination", NLYpagination);
}
};
在main.js中引入添加以下代码引入index.js
import pagination from "./components/index.js";
Vue.use(pagination);
完整的main.js应该是这样
9、 demo
在需要分页组件的地方,使用组件就行。
<template>
<NLY-pagination
ref="pagination"
:total="total"
:size="size"
:limit="limit"
align="center"
:currentPage="currentPage"
:firstFunction="firstFunction"
:prevFunction="prevFunction"
:currentFunction="currentFunction"
:nextFunction="nextFunction"
:lastFunction="lastFunction"
:sizeFunction="sizeFunction"
@getCurrentPage="getCurrentPage"
/>
</template>
<script>
export default {
data() {
return {
currentPage: 1,
total: 100,
size: 10,
limit: 5
};
},
methods: {
firstFunction() {
console.log(
`跳到第一页: 从第 ${this.currentPage} 页跳转到 ${this.$refs["pagination"].tempalteCurrentPage} 页`
);
},
prevFunction() {
console.log(
`跳到上一页: 从第 ${this.currentPage} 页跳转到 ${this.$refs["pagination"].tempalteCurrentPage} 页`
);
},
currentFunction() {
console.log(
`点击跳转到当前点击页码页面: 从第 ${this.currentPage} 页跳转到 ${this.$refs["pagination"].tempalteCurrentPage} 页`
);
},
nextFunction() {
console.log(
`跳到下一页: 从第 ${this.currentPage} 页跳转到 ${this.$refs["pagination"].tempalteCurrentPage} 页`
);
},
lastFunction() {
console.log(
`跳到最后一页: 从第 ${this.currentPage} 页跳转到 ${this.$refs["pagination"].tempalteCurrentPage} 页`
);
},
sizeFunction() {
console.log("修改每页数量");
},
getCurrentPage(data) {
this.currentPage = data;
},
getPages(val) {
console.log(val);
}
}
};
</script>
<!--
total: 总数
size: 每页数量,默认10
currentPage: 初始页码
limit: 显示页码个数
align:分页位置,left左边,center中间,right右边,默认左边
firstFunction: 第一页按钮函数
prevFunction: 上一页按钮函数
currentFunction: 点击页码函数
nextFunction: 下一页页码函数
lastFunction: 最后一页页码函数
sizeFunction: 修改每页数量自动执行函数
-->
演示效果如下: