一、Vue分页参数
Vue分页中,我们需要了解分页相关的参数,以便配置分页组件。常用的分页参数包括:
- 当前页数:用于标识当前显示的页码,可以通过v-model绑定到当前页数的变量上。
- 总记录数:用于计算总页数,参与分页算法。可以从后端接口获取。
- 每页显示数:用于控制每页显示的记录数,也叫分页大小。
- 页码范围:用于控制分页器上显示的页码数量,通常显示3~5个页码。
代码示例:
<template> <div class="pagination"> <span>总共 {{ total }} 条记录</span> <ul> <li v-if="currentPage>1"><a href="#" @click.prevent="currentPage--"><</a></li> <li v-for="page in pages"><a href="#" @click.prevent="currentPage=page">{{ page }}</a></li> <li v-if="currentPage<totalPage"><a href="#" @click.prevent="currentPage++">></a></li> </ul> </div> </template> <script> export default { name: "Pagination", props: { total: Number, pageSize: { type: Number, default: 10 }, range: { type: Number, default: 3 }, currentPage: { type: Number, default: 1 }, }, computed: { totalPage () { return Math.ceil(this.total / this.pageSize) }, pages () { let from = Math.max(1, this.currentPage - this.range) let to = Math.min(this.totalPage, this.currentPage + this.range) let pages = [] for (let i = from; i <= to; i++) { pages.push(i) } return pages }, }, } </script>
二、Vue分页面
Vue分页面是指根据后端接口返回的数据进行前端分页处理展示。
示例页面中,我们需要获取分页参数后,通过计算得到展示的分页列表,再将每页显示数和当前页码作为参数传递给后端接口获取分页数据。分页数据获取后,需要用v-for指令进行循环展示。
代码示例:
<template> <div class="pagination"> <ul> <li v-for="item in pagedData" :key="item.id">{{ item.title }}</li> </ul> <pagination :total="total" :pageSize="pageSize" @update:currentPage="loadPageData" /> </div> </template> <script> import Pagination from "@/components/Pagination"; export default { components: { Pagination }, data () { return { currentPage: 1, pageSize: 10, total: 100, data: [] } }, created () { this.loadData() }, methods: { async loadData () { // 模拟后端返回数据 let res = await fetch(`api/data?page=${this.currentPage}&size=${this.pageSize}`) let { data, total } = await res.json() this.data = data this.total = total }, loadPageData (currentPage) { this.currentPage = currentPage this.loadData() } }, computed: { pagedData () { let start = (this.currentPage - 1) * this.pageSize let end = start + this.pageSize return this.data.slice(start, end) } } } </script>
三、Vue分页组件
为了方便重复使用,在Vue中可以封装成一个组件进行调用。常用的分页组件包括:element-ui的Pagination、bootstrap-vue的b-pagination、vue-pagination等,这里以element-ui为例介绍。
element-ui的Pagination组件需要注意的是,它的currentPage属性要使用v-model绑定。此外,该组件还提供了一个layout属性,用于自定义分页器布局,可以通过字符串数组来指定布局元素的位置。
代码示例:
<template> <div> <el-pagination layout="total,sizes,prev,pager,next,jumper" :page-sizes="[10, 20, 50, 100]" :total="total" :page-size="pageSize" v-model="currentPage" @current-change="loadData" /> <ul> <li v-for="item in data" :key="item.id">{{ item.title }}</li> </ul> </div> </template> <script> import { Pagination } from "element-ui"; export default { components: { [Pagination.name]: Pagination }, data () { return { currentPage: 1, pageSize: 10, total: 100, data: [] } }, mounted () { this.loadData() }, methods: { async loadData () { // 模拟后端返回数据 let res = await fetch(`api/data?page=${this.currentPage}&size=${this.pageSize}`) let { data, total } = await res.json() this.data = data this.total = total } } } </script>
四、Vue分页展示图片
在Vue分页过程中,我们可能需要在分页中展示图片,可以使用v-bind绑定src属性,或使用Vue的require方法引入图片资源。
代码示例:
<template> <ul> <li v-for="item in data" :key="item.id"> <img :src="item.imageUrl"> {{ item.title }} </li> </ul> </template> <script> export default { data () { return { data: [ { id: 1, title: 'title1', imageUrl: require('@/assets/img1.jpg') }, { id: 2, title: 'title2', imageUrl: require('@/assets/img2.jpg') }, { id: 3, title: 'title3', imageUrl: require('@/assets/img3.jpg') }, ... ] } } } </script>
五、Vue分页查询
在Vue分页中,我们可以添加数据查询功能,让用户根据关键字等条件进行数据检索。对于数据查询,通常需要向后台服务器发送请求,并传递查询参数。查询分页逻辑需要在后端服务器进行处理,这里只展示前端的代码。
代码示例:
<template> <div> <input v-model.trim="keyword" placeholder="请输入关键字"> <button @click="searchData">搜索</button> <el-pagination ... /> <ul> <li v-for="item in data" :key="item.id">{{ item.title }}</li> </ul> </div> </template> <script> import { Pagination } from "element-ui"; export default { components: { [Pagination.name]: Pagination }, data () { return { keyword: "", currentPage: 1, pageSize: 10, total: 0, data: [] } }, methods: { async searchData () { // 模拟后端返回数据 let res = await fetch(`api/data?page=${this.currentPage}&size=${this.pageSize}&keyword=${this.keyword}`) let { data, total } = await res.json() this.data = data this.total = total }, async loadData () { // 模拟后端返回数据 let res = await fetch(`api/data?page=${this.currentPage}&size=${this.pageSize}`) let { data, total } = await res.json() this.data = data this.total = total } } } </script>
六、Vue分页原理
Vue分页的原理是通过前端计算获得分页数据,这个过程通过计算分页参数得出分页器上显示的页码列表,然后根据当前页码、每页显示数、数据总记录数等参数计算出当前页码的数据索引,再根据索引获取相关的分页数据。
代码示例:
<template> <div> <ul> <li v-for="item in pagedData">{{ item.title }}</li> </ul> <div v-if="totalPage"> <button @click="setCurrentPage(1)" :disabled="currentPage === 1">首页</button> <button @click="setCurrentPage(currentPage-1)" :disabled="currentPage === 1">上一页</button> <button v-for="page in pages" :key="page" @click="setCurrentPage(page)" :class="{ 'active': page === currentPage }" >{{ page }}</button> <button @click="setCurrentPage(currentPage+1)" :disabled="currentPage === totalPage">下一页</button> <button @click="setCurrentPage(totalPage)" :disabled="currentPage === totalPage">尾页</button> </div> </div> </template> <script> export default { data () { return { currentPage: 1, pageSize: 10, total: 100, data: [] } }, computed: { totalPage () { return Math.ceil(this.total / this.pageSize) }, pages () { let from = Math.max(1, this.currentPage - 2) let to = Math.min(this.totalPage, this.currentPage + 2) let pages = [] for (let i = from; i <= to; i++) { pages.push(i) } return pages }, pagedData () { let start = (this.currentPage - 1) * this.pageSize let end = start + this.pageSize return this.data.slice(start, end) } }, methods: { setCurrentPage (page) { if (page < 1 || page > this.totalPage) { return } this.currentPage = page this.loadData() }, async loadData () { // 模拟后端返回数据 let res = await fetch(`data?page=${this.currentPage}&size=${this.pageSize}`) let { data, total } = await res.json() this.data = data this.total = total } }, mounted () { this.loadData() } } </script>
七、Vue分页函数
分页函数是一段封装好的可以在Vue分页中重复使用的代码。
代码示例:
<template> <div> <ul> <li v-for="item in pagedData">{{ item.title }}</li> </ul> <div v-if="totalPage"> <button @click="setCurrentPage(1)" :disabled="currentPage === 1">首页</button> <button @click="setCurrentPage(currentPage-1)" :disabled="currentPage === 1">上一页</button> <button v-for="page in pages" :key="page" @click="setCurrentPage(page)" :class="{ 'active': page === currentPage }" >{{ page }}</button> <button @click="setCurrentPage(currentPage+1)" :disabled="currentPage === totalPage">下一页</button> <button @click="setCurrentPage(totalPage)" :disabled="currentPage === totalPage">尾页<