前言
在实际开发中,大部分分页都是配合后端完成的。但是,有时候并不是这样,并非不是这样。后端会一次性返回所有的数据,而我们前端不可能展示所有数据,而是弄一个分页效果。还有一些场景也是需要前端自己弄的分页,如:上传一个Excel表格展示到要页面,当表格的数据足够多,我们也需要弄一个分页效果。
现在,我就带大家用数组中的
slice
方法在Vue中实现前端分页效果。
原理
实现前端分页并不难,用需要用到数组的一个方法
slice
,看看官网对这个方法的介绍:slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。看完这句话,我们知道该方法在不破坏原数组的情况下返回一个新的数组。其实就对数据切割,并返回被切割的片段。
slice
方法最多可接收两个参数,可传一个或者不传。通过下面栗子来认识这个方法的使用。
使用1:不传递参数
很明显,当我们不传参数的时候,它会**返回整个数组**给我们。也就是说,不传参数的时候,他不会对原数组进行切割。
// 准备一个数组const sect =['少林派','武当派','逍遥派','峨眉派','华山派','日月神教','古墓派','全真教','丐帮','明教']// slice 不传参数const newSect = sect.slice()
console.log(newSect)// (10) ['少林派', '武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']
使用2:传递一个参数
很明显,当我们传一个参数的时候,它会切割后的数组给我们:
- 当我们传1的时候,它会从索引为1的元素开始截取直到最后一个元素。
- 当我们传6的时候,它会从索引为6的元素开始截取直到最后一个元素。
- 当我们传10的时候,它会从索引为10的元素开始截取取直到最后一个元素。因为这个数组的长度为10,所以他的最大索引为
9
。所以当第一个参数比数组索引大,就会返回空的数组,这也是情理之中。 - 当我们传
-2
的时候,它会从索引为8的元素来说截取,为什么从8开始? 当参数为负数的时候,给大家一个公式:arr.length + 参数
,在这个例子就是:10 + (-2) = 8
。你也可以说他是反过来数的,也没毛病!(理解最大)
也就是说,传递一个参数时,它会截取从索引为第一个参数到最后一个元素,并返回给我们。当参数比最大索引还大时,会返回空数组;当参数为负数是,它会反着数起始截取位置(不理解的可以使用上面的公式)。
// 准备一个数组const sect =['少林派','武当派','逍遥派','峨眉派','华山派','日月神教','古墓派','全真教','丐帮','明教']const newSect1 = sect.slice(1)const newSect2 = sect.slice(6)const newSect3 = sect.sect(10)const newSect4 = sect.slice(-2)
console.log(newSect1)// (9) ['武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']
console.log(newSect2)// (4) ['古墓派', '全真教', '丐帮', '明教']
console.log(newSect3)// []
console.log(newSect4)// (2) ['丐帮', '明教']
使用3:传递两个参数
很明显,当我们传两个参数的时候,它也会切割后的数组给我们,但是截取不一定到最后一个元素:
- 当我们传0和2的时候,它会从索引为0开始截取直到索引为2的元素(不包括索引为2的元素)。
- 当我们传8和20的时候,它会从索引为8开始截取直到索引为20的元素(不包括索引为2的元素)。因为这个
sect
数组的的最大索引为9
,他只会截取索引为8和9的元素。也可以怎么说:当第二个参数比数组的最大索引还大,就会截取到最后一个元素。 - 当我们传
-2和-1
的时候,它会从索引为8开始截取直到索引为9的元素(不包括索引为9的元素)。又是为什么呢? 这里我们也可以使用上面的公式:arr.length + 参数
,在这个例子就是,第一个参数:10 + (-2) = 8
,第二个参数:10 + (-1) = 9
,所以就是 *sect.slcie(8, 9)*。 - 当我们传
-2和-3
的时候,原理上它会从索引为8开始截取直到索引为7的元素(不包括索引为7的元素)。这个情况比较特殊,它会返回一个空数组,因为截取是从左往右
而不是从右往左
。
也就是说,传递两个参数时,它会截取从索引为第一个参数开始到索引为第二个参数(不包含这个索引)结束,并返回给我们。当第二个参数比最大索引还大时,会截取到最后一个元素;当第二个参数比第一个参数小时,会返回空数组;当参数为负数是,它会反着数起始截取位置(不理解的可以使用上面的公式)。
// 还是准备一个数组const sect =['少林派','武当派','逍遥派','峨眉派','华山派','日月神教','古墓派','全真教','丐帮','明教']const newSect1 = sect.slice(0,2)const newSect2 = sect.slice(8,20)const newSect3 = sect.slice(-2,-1)const newSect4 = sect.slice(-2,-3)
console.log(newSect1)// (2) ['少林派', '武当派']
console.log(newSect2)// (2) ['丐帮', '明教']
console.log(newSect3)// (1) ['丐帮']
console.log(newSect4)// []
如果你对这个方法很熟,你可以跳过上面的内容,直接阅读下面的内容。如果你都很熟,我相信大佬一定会不吝赐教的!!!
实现
思路:**在vue的生命周期函数中,请求全部数据,存到一个数组中。然后封装一个截取数组的方法对存全部数据的数组进行截取,每次调用都返回你想要的数组片段,以实现分页效果。这里使用
element-ui
vue
演练:**
在data中定义一个接受总数据的变量、一个真正展示的数据的变量(也就是,存放在总数据的数组中截取出来的片段)、一个总页数的变量(也就是,总数据的长度)、一个当前页的变量(默认是第一页)、一个没有大小的变量(默认为每页10条数据)。 在vue的生命周期函数中,获取全部数据并存到放总数据的变量:
tableData
中,然后调用
queryByPage
方法对总数据进行截取,默认截取10条数据(索引为0 - 9),将截取后的数据保存到真正展示数据的变量
pageData
中。这里一上来就展示10条数据了,当我们改变当前页或者每页大小时,修改变量currentPage或者pageSize,然后执行
queryByPage
就可以截取我们想要的片段了。
具体
queryByPage
方法是怎么实现的:
- 当展示第1页并每页10条数据时:应当截取索引
0-9
的数据,即tableData.slice(0, 10)
=>currentPage = 1;pageSize = 10
。- 当展示第1页并每页20条数据时:应当截取索引
0-19
的数据,即tableData.slice(0, 20)
=>currentPage = 1;pageSize = 20
。- 当展示第2页并每页10条数据时:应当截取索引
10-19
的数据,即tableData.slice(10, 20)
=>currentPage = 2;pageSize = 20
。此时可以推出一个公式:tableData.slice((currentPage - 1) x pageSize, currentPage x pageSize)
Vue2版
<template><el-cardclass="box-card"><divslot="header"class="clearfix"><span>vue2实现前端分页</span></div><el-table:data="pageData"bordersize="mini"style="width: 100%"><el-table-columnprop="name"label="姓名"width="120"align="center"/><el-table-columnprop="age"label="年龄"width="80"align="center"/><el-table-columnprop="describe"label="描述"align="center"/></el-table><el-paginationstyle="margin-top: 12px;text-align: right;"@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage":page-sizes="[10, 20, 50, 100]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="pageTotal"></el-pagination></el-card></template><script>import axios from'axios'exportdefault{data(){return{// 总的数据tableData:[],// 分页的数据pageData:[],// 总数据量 默认为 0pageTotal:0,// 当前页 默认是第一页currentPage:1,// 每页大小 默认每页10条数据pageSize:10}},created(){this.fetchData()},methods:{// 改变每页大小的回调handleSizeChange(val){this.pageSize = val
this.pageData =this.queryByPage()},// 改变当前页的回调handleCurrentChange(val){this.currentPage = val
this.pageData =this.queryByPage()},// 获取全部数据asyncfetchData(){// pubic/table_data.json :默认请求后端数据const{ data }=await axios.get('/table_data.json')this.tableData = data.data
this.pageTotal = data.data.length
this.pageData =this.queryByPage()},// 实现分页的方法queryByPage(){// 起始位置 = (当前页 - 1) x 每页的大小const start =(this.currentPage -1)*this.pageSize
// 结束位置 = 当前页 x 每页的大小const end =this.currentPage *this.pageSize
returnthis.tableData.slice(start, end)}}}</script>
Vue3版
<scriptsetuplang="ts">import axios from"axios"import{ reactive, onMounted }from"vue"// 表格数据接口interfaceITable{name: string;age: number;describe: string;}let data =reactive({tableData:[]as ITable[],// 总的数据pageData:[]as ITable[],// 分页的数据currentPage:1,// 当前页 默认是第一页pageSize:10,// 每页大小 默认每页10条数据pageTotal:0// 总数据量 默认为 0})// 在声明周期函数获取数据onMounted(()=>{fetchData()})constfetchData=async()=>{// pubic/table_data.json :默认请求后端数据const result =await axios.get("/table_data.json")
data.tableData = result.data.data
data.pageTotal = result.data.data.length
data.pageData =queryByPage()}// 实现分页的方法const queryByPage =(): ITable[]=>{// 起始位置 = (当前页 - 1) x 每页的大小let start =(data.currentPage -1)* data.pageSize
// 结束位置 = 当前页 x 每页的大小let end = data.currentPage * data.pageSize
// 返回切割数组后的数据return data.tableData.slice(start, end)}// 改变每页大小的方法consthandleSizeChange=(val: number)=>{
data.pageSize = val
data.pageData =queryByPage()}// 改变当前页的方法consthandleCurrentChange=(val: number)=>{
data.currentPage = val
data.pageData =queryByPage()}</script><template><el-cardclass="box-card"style="width: 70%;"><template#header><divclass="card-header"><span>vue3实现前端分页</span></div></template><el-table:data="data.pageData"borderstyle="width: 100%;"><el-table-columnprop="name"label="姓名"width="150"align="center"/><el-table-columnprop="age"label="年龄"width="80"align="center"/><el-table-columnprop="describe"label="描述"align="center"/></el-table><el-paginationv-model:currentPage="data.currentPage"v-model:page-size="data.pageSize":page-sizes="[10, 20, 50, 100]":background="true"layout="total, sizes, prev, pager, next, jumper":total="data.pageTotal"@size-change="handleSizeChange"@current-change="handleCurrentChange"style="margin-top: 12px;display: flex;justify-content: flex-end;"/></el-card></template>
|
版权归原作者 vernin 所有, 如有侵权,请联系我们删除。