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实现的有很多缺陷,甚至需求都不明白,最后只能自己一步一步实现,想了很多方案,最终在此方案下符合需求。

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

效果


完整代码

相关推荐
yinmaisoft几秒前
6 大数据库一键连!JNPF 数据中心数据源链接,表单数据互通无压力
前端·数据库·低代码·信息可视化
MicroTech20251 分钟前
MLGO微算法科技发布基于RANSAC-ISS-3DSC改进ICP的激光扫描仪点云快速配准算法
科技·算法·3d
黛色正浓2 分钟前
【React】极客园案例实践-发布文章模块
前端·react.js·前端框架
开发者小天4 分钟前
react的组件库antd design表格多选,删除的基础示例
前端·javascript·react.js
_OP_CHEN4 分钟前
【算法基础篇】(二十六)数据结构封神!Trie 树从入门到爆杀算法题:拼音输入法、单词统计都靠它
数据结构·c++·算法·蓝桥杯·trie树·算法竞赛·acm/icpc
代码游侠8 分钟前
数据结构--队列
数据结构·笔记·学习·算法·链表
by__csdn10 分钟前
Vue3响应式系统详解:ref与reactive全面解析
前端·javascript·vue.js·typescript·ecmascript·css3·html5
渴望成为python大神的前端小菜鸟11 分钟前
react 面试题
前端·react.js·前端框架·react·面试题
Greatlifeee12 分钟前
基于vue3+ts的前端网页,实现网页点击按钮打开本地exe运行文件的完整实例
前端