• 前端实现分页效果


    前言

            在实际开发中,大部分分页都是配合后端完成的。但是,有时候并不是这样,并非不是这样。后端会一次性返回所有的数据,而我们前端不可能展示所有数据,而是弄一个分页效果。还有一些场景也是需要前端自己弄的分页,如:上传一个Excel表格展示到要页面,当表格的数据足够多,我们也需要弄一个分页效果。

            现在,我就带大家用数组中的slice方法在Vue中实现前端分页效果。

    原理

            实现前端分页并不难,用需要用到数组的一个方法slice,看看官网对这个方法的介绍:slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。看完这句话,我们知道该方法在不破坏原数组的情况下返回一个新的数组。其实就对数据切割,并返回被切割的片段。

            slice方法最多可接收两个参数,可传一个或者不传。通过下面栗子来认识这个方法的使用。

    使用1:不传递参数

            很明显,当我们不传参数的时候,它会返回整个数组给我们。也就是说,不传参数的时候,他不会对原数组进行切割。

    // 准备一个数组
    const sect = ['少林派', '武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']
    
    // slice 不传参数
    
    const newSect = sect.slice()
    
    console.log(newSect)
    // (10) ['少林派', '武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    使用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) ['丐帮', '明教']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    使用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)
    // []
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    如果你对这个方法很熟,你可以跳过上面的内容,直接阅读下面的内容。如果你都很熟,我相信大佬一定会不吝赐教的!!!

    实现

    思路:在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-card class="box-card">
        <div slot="header" class="clearfix">
          <span>vue2实现前端分页span>
        div>
        <el-table
            :data="pageData"
            border
            size="mini"
            style="width: 100%">
            <el-table-column prop="name" label="姓名" width="120" align="center" />
            <el-table-column prop="age" label="年龄" width="80" align="center" />
            <el-table-column prop="describe" label="描述" align="center" />
          el-table>
    
          <el-pagination
            style="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'
    export default {
      data () {
        return {
          // 总的数据
          tableData: [],
          // 分页的数据
          pageData: [],
          // 总数据量 默认为 0
          pageTotal: 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()
        },
        // 获取全部数据
        async fetchData () {
          // 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
    
          return this.tableData.slice(start, end)
        }
      }
    }
    script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84

    Vue3版

    <script setup lang="ts">
    	import axios from "axios"
    	import { reactive, onMounted } from "vue"
    
    	// 表格数据接口
    	interface ITable {
    		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()
    	})
    
    	const fetchData = 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)
    	}
    
    	// 改变每页大小的方法
    	const handleSizeChange = (val: number) => {
    		data.pageSize = val
    		
    		data.pageData = queryByPage()
    	}
    
    	// 改变当前页的方法
    	const handleCurrentChange = (val: number) => {
    		data.currentPage = val
    		
    		data.pageData = queryByPage()
    	}
    script>
    
    <template>
    	<el-card class="box-card" style="width: 70%;">
        <template #header>
          <div class="card-header">
            <span>vue3实现前端分页span>
          div>
        template>
    		<el-table :data="data.pageData" border style="width: 100%;">
        <el-table-column prop="name" label="姓名" width="150" align="center" />
        <el-table-column prop="age" label="年龄" width="80" align="center" />
        <el-table-column prop="describe" label="描述" align="center" />
      el-table>
    	<el-pagination
    		v-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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    | 在这里插入图片描述

  • 相关阅读:
    Android 10.0 Launcher3定制化之folder文件夹文件居中显示的功能实现
    sherpa + ncnn 离线语音识别
    火山中文编程 -- 读写配置文件
    如何利用 Media Creation Tool 来创建安装介质或下载 ISO 文件
    SIGIR 2021 | UPFD:用户偏好感知假新闻检测
    ubuntu 18.04 安装ffmpeg
    深入源码剖析String类为什么不可变?(还不明白就来打我)
    第六季完美童模 代言人段沫如 全球赛个人风采展示
    golang数组
    NOIP1998-2018 CSP-S2 2019 2021提高组解题报告与视频
  • 原文地址:https://blog.csdn.net/weixin_48165407/article/details/126790480