vue3.2 前端动态分页算法

文章目录

背景

javascript 复制代码
   1. 后台接口只是动态返回一个数组的数据,前端需要根据数据量的大小判断是否需要分页,页面高度固定
   2. 页面根据页数大小有不同的展示
     a. 只有一页  头部 + 内容 + 统计 + 尾部
     b. 多页
        i.  第一页 头部 + 内容 + 尾部
        ii. 中间页 内容 + 尾部
        iii. 最后一页 内容 + 统计 + 尾部

思路

javascript 复制代码
	1. 先判断是否一页能满足 如果能满足 不做数据处理
	2. 不满足则肯定是多页
	    a. 先计算第一页的逻辑,将数组分为[第一页数据, 剩余数据]
	    b. 剩余数据只有两种情况
	      i. 符合尾页逻辑 直接将剩余数据放入最后一页
	     ii. 不符合尾页逻辑 递归实现中间页

页面情况

javascript 复制代码
 s1 只有一页  不需要操作
 
 s2 多页
    a. 第一页因为要显示头部  所以高度为  540 - 50
    b. 中间页只显示内容      所以高度为  540
    c. 尾页因为要显示统计    所以高度为  540 - 50

核心代码

javascript 复制代码
<template>
  <div class="container">
    <div class="page" v-for="(list, index) in lists" :key="index">
      <div class="top" v-if="index === 0">
        <VHead />
      </div>

      <div class="middle">
        <VTable :item="list" />
        <VTotal v-if="index === lists.length - 1" />
      </div>

      <div class="bottom">
        <VFooter />
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick } from 'vue'
import VHead from './components/VHead.vue'
import VTable from './components/VTable.vue'
import VTotal from './components/VTotal.vue'
import VFooter from './components/VFooter.vue'
import { init } from './data/index.js'

const HEIGHT = 540

const list = init(5)
const lists = ref([])

const render = async () => {
  lists.value = [list]
  await nextTick()
  calculatePages()
}

const getTrs = () => {
  const trEls = document.querySelectorAll('.v-table tbody tr')
  let trHeights = []
  for (let i = 0; i < trEls.length; i++) {
    trHeights.push(trEls[i].offsetHeight)
  }
  const trHeightsTotal = trHeights.reduce((acc, cur) => acc + cur, 0)
  return {
    trHeights,
    trHeightsTotal
  }
}

const calculatePages = () => {
  const isSiglePage = getIsSinglePage()
  if (!isSiglePage) {
    const remainIndex = calculateFirstPage()
    lists.value = [list.slice(0, remainIndex)]
    calculateOtherPages(remainIndex)
  }
}

const getIsSinglePage = () => {
  const { trHeightsTotal } = getTrs()
  if (trHeightsTotal + 100 > HEIGHT) {
    return false
  }
  return true
}

const calculateFirstPage = () => {
  const { trHeights } = getTrs()
  const maxHeight = HEIGHT - 50
  let total = 0
  let index = 0
  for (let i = 0; i < trHeights.length; i++) {
    if (total + trHeights[i] > maxHeight) {
      break
    }
    total += trHeights[i]
    index = i
  }
  return index
}

const calculateOtherPages = (remainIndex) => {
  const { trHeights } = getTrs()
  const remainTrHeights = trHeights.slice(remainIndex)
  const remainTrTotal = remainTrHeights.reduce((acc, cur) => acc + cur, 0)
  if (remainTrTotal + 50 > HEIGHT) {
    let total = 0
    let index = 0
    for (let i = remainIndex; i < trHeights.length; i++) {
      if (total + trHeights[i] > HEIGHT) {
        break
      }
      total += trHeights[i]
      index = i
    }
    if (index) {
      lists.value.push(list.slice(remainIndex, index))
      calculateOtherPages(index)
    }
  } else {
    lists.value.push(list.slice(remainIndex))
  }
}

onMounted(() => {
  render()
})
</script>

<style lang="scss" scoped>
.container {
  display: flex;
  flex-direction: column;
}

.page {
  width: 800px;
  height: 590px;
  border: 1px solid #ccc;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  margin-bottom: 2px;
  overflow: hidden;

  .top,
  .bottom {
    height: 50px;
  }

  .middle {
    flex: 1;
    overflow: hidden;
  }
}
</style>

小结

最开始想的是通过AI实现,经过多次测试发现AI实现的有很多缺陷,甚至需求都不明白,最后只能自己一步一步实现,想了很多方案,最终在此方案下符合需求。

如果有更好的方案,欢迎交流

效果


完整代码

相关推荐
程序员Xu27 分钟前
【OD机试题解法笔记】连续出牌数量
笔记·算法·深度优先
CoovallyAIHub40 分钟前
单目深度估计重大突破:无需标签,精度超越 SOTA!西湖大学团队提出多教师蒸馏新方案
深度学习·算法·计算机视觉
袁煦丞40 分钟前
【局域网秒传神器】LocalSend:cpolar内网穿透实验室第418个成功挑战
前端·程序员·远程工作
江城开朗的豌豆41 分钟前
Vuex数据突然消失?六招教你轻松找回来!
前端·javascript·vue.js
CoovallyAIHub43 分钟前
从FCOS3D到PGD:看深度估计如何快速搭建你的3D检测项目
深度学习·算法·计算机视觉
好奇心笔记1 小时前
ai写代码随机拉大的,所以我准备给AI出一个设计规范
前端·javascript
江城开朗的豌豆1 小时前
Vue状态管理进阶:数据到底是怎么"跑"的?
前端·javascript·vue.js
用户21411832636021 小时前
dify案例分享-Dify v1.6.0 重磅升级:双向 MCP 协议引爆 AI 生态互联革命
前端
程序员海军1 小时前
AI领域又新增协议: AG-UI
前端·openai·agent
我想说一句1 小时前
React待办事项开发记:Hook魔法与组件间的悄悄话
前端·javascript·前端框架