当前位置: 首页 > article >正文

自研国产零依赖前端UI框架实战006 实现表格分页的功能

前言

通过前面的努力, 我们已经封装了第一个表格组件, 但是我们还没有实现分页的功能.

分页这个功能在web开发中属于比较常见的了, 我们最好不要和table组件放一块, 可以单独封装一下.

那么我们直接开开搞吧.

基础分页

首先我们在App.vue里面添加分页的元素:

<div class="page">
      <ul>
        <li>上一页</li>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>下一页</li>
      </ul>
    </div>

此时还比较丑:

在这里插入图片描述

我们美化一下样式, 让其实现居中对齐, 充满科技感的分页效果.

<script setup>
import zdp_table1 from "./zdpui/components/zdp_table1.vue";
import random from "./zdpui/js/random.js";

const columns = [
  {
    title: "员工编号",
    key: "id",
    width: 80,
    align: "center"
  },
  {
    title: "姓名",
    key: "name",
    width: 100,
    align: "center"
  },
  {
    title: "年龄",
    key: "age",
    width: 100,
    align: "center"
  }
]
const data = random.users(3)
</script>
<template>
  <div>
    <zdp_table1
        :columns="columns"
        :data="data"
    />
    <div class="page">
      <ul>
        <li>首页</li>
        <li>上一页</li>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>下一页</li>
        <li>末页</li>
      </ul>
    </div>
  </div>
</template>
<style scoped>
.page {
  width: fit-content;
  margin: 0 auto;
  display: flex;
  justify-content: center;
  align-items: center;
}

.page ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
  display: flex;
}

.page ul li {
  margin: 0 10px;
  padding: 10px 20px;
  cursor: pointer;
  border-radius: 5px;
  color: #fff;
  transition: all 0.3s ease;
  /* 使用线性渐变作为背景 */
  background: linear-gradient(to bottom, #00A8FF, #0088cc);
}

.page ul li:hover {
  /* 悬停时使用更亮的渐变 */
  background: linear-gradient(to bottom, #00C8FF, #00A8FF);
  box-shadow: 0 0 10px rgba(0, 168, 255, 0.8);
  transform: translateY(-2px);
}

.page ul li:active {
  /* 点击时使用稍暗的渐变 */
  background: linear-gradient(to bottom, #0088cc, #0066aa);
  box-shadow: 0 0 5px rgba(0, 102, 170, 0.8) inset;
  transform: scale(0.95);
}
</style>

这个时候界面渲染效果如下, 美观多了.

在这里插入图片描述

封装分页组件

接下来就把分页相关的功能封装到一个组件中, 这样便于独立的维护和复用.

处于分页也可能有多种分页的考虑,我决定封装一个zdp_page1这样的组件.

此时, 我的项目结构如下:

在这里插入图片描述

界面的渲染效果还是原来那样, 很完美, 此时App.vue完整代码如下:

<script setup>
import zdp_table1 from "./zdpui/components/zdp_table1.vue";
import zdp_page1 from "./zdpui/components/zdp_page1.vue";
import random from "./zdpui/js/random.js";

const columns = [
  {
    title: "员工编号",
    key: "id",
    width: 80,
    align: "center"
  },
  {
    title: "姓名",
    key: "name",
    width: 100,
    align: "center"
  },
  {
    title: "年龄",
    key: "age",
    width: 100,
    align: "center"
  }
]
const data = random.users(3)
</script>
<template>
  <div>
    <zdp_table1
        :columns="columns"
        :data="data"
    />
    <zdp_page1/>
  </div>
</template>

完善分页组件

当前的分页组件过于简单了, 不支持传参, 也不支持监听点击事件, 我们来优化一下.

首先, 在分页的样式文件里面加一种激活时的样式:

.page1 ul li.active {
  background-color: #FF4500;
  background-image: linear-gradient(rgb(5, 39, 175), rgb(30, 60, 200));
  color: white;
}

接着调整分页组件的代码:

<script setup>
import {ref, computed} from 'vue';
import "../css/page.css";

// 接收外部传入的当前页、每页数量和总数据量
const props = defineProps({
  page: {
    type: Number,
    default: 1,
  },
  size: {
    type: Number,
    default: 8,
  },
  total: {
    type: Number,
    default: 100,
  }
});

// 计算总页数
const totalPage = computed(() => Math.ceil(props.total / props.size));

// 计算可见的分页按钮数字
const visiblePages = computed(() => {
  let start = Math.max(1, props.page - 2);
  let end = Math.min(totalPage.value, props.page + 2);
  let pages = [];
  for (let i = start; i <= end; i++) pages.push(i)
  return pages;
});

// 触发点击事件,更新当前页并发出事件
const emit = defineEmits(['change']);
const goToPage = (page) => {
  if (page < 1) page = 1;
  if (page > totalPage.value) page = totalPage.value;
  emit('change', page);
};
</script>


<template>
  <div class="page1">
    <ul>
      <li @click="goToPage(1)">首页</li>
      <li @click="goToPage(page - 1)">上一页</li>
      <!-- 显示当前页前两页和后两页 -->
      <li
          v-for="v in visiblePages"
          :key="v"
          :class="{ active: v === page }"
          @click="goToPage(v)"
      >
        {{ v }}
      </li>
      <li @click="goToPage(page + 1)">下一页</li>
      <li @click="goToPage(totalPage)">末页</li>
    </ul>
  </div>
</template>

修改一下App.vue, 使用这个分页组件:

<script setup>
import zdp_table1 from "./zdpui/components/zdp_table1.vue";
import zdp_page1 from "./zdpui/components/zdp_page1.vue";
import random from "./zdpui/js/random.js";
import {ref} from "vue";

const columns = [
  {
    title: "员工编号",
    key: "id",
    width: 80,
    align: "center"
  },
  {
    title: "姓名",
    key: "name",
    width: 100,
    align: "center"
  },
  {
    title: "年龄",
    key: "age",
    width: 100,
    align: "center"
  }
]
const data = random.users(3)

const page = ref(1);
const size = ref(10);
const total = ref(100);

const onChangePage = (v) => page.value = v
</script>
<template>
  <div>
    <zdp_table1
        :columns="columns"
        :data="data"
    />
    <zdp_page1
        :page="page"
        :size="size"
        :total="total"
        @change="onChangePage"
    />
  </div>
</template>

此时分页的效果就更加的好看了, 而且点击的时候会动态切换分页.

在这里插入图片描述

不过我们分页变化以后, 数据并没有跟着变化, 我们继续完善一下代码.

数据随着分页改变

要实现数据随着分页改变, 最简单的方式就是分页变化以后, 重新生成随机的用户数据.

const page = ref(1);
const size = ref(10);
const total = ref(100);
const data = ref(random.users(size.value))

const onChangePage = (v) => {
  page.value = v
  data.value = random.users(size.value)
}

这个时候每次点击分页, 可以发现数据都会变化, 但是前面的id并没有跟着变.

那么该怎么解决这个id没有跟着变化的问题呢?

我想到的一个解决方案就是增强随机数据模块, 提供一个根据分页获取随机用户信息的方法. 这个方法返回的是一个对象, 对象中用total标记总共有多少条数据, 用data存储当前页的数据.

解决id不变的问题

在随机模块中增加一个分页获取用户信息的方法:

function getPageUser(
    page = 1,
    size = 8,
    total = 888,
) {
    const startIndex = (page - 1) * size;
    const endIndex = startIndex + size;
    const result = [];
    let id = startIndex + 1;
    for (let i = startIndex; i < endIndex && i < total; i++) {
        result.push({
            id: id++,
            name: name(),
            age: age()
        });
    }
    return {
        total: total,
        data: result
    };
}

修改App.vue, 分页获取用户数据:

<script setup>
import zdp_table1 from "./zdpui/components/zdp_table1.vue";
import zdp_page1 from "./zdpui/components/zdp_page1.vue";
import random from "./zdpui/js/random.js";
import {ref} from "vue";

const columns = [
  {
    title: "员工编号",
    key: "id",
    width: 80,
    align: "center"
  },
  {
    title: "姓名",
    key: "name",
    width: 100,
    align: "center"
  },
  {
    title: "年龄",
    key: "age",
    width: 100,
    align: "center"
  }
]

const page = ref(1);
const size = ref(10);
const total = ref(100);
const data = ref(random.users(size.value))

const onChangePage = (v) => {
  page.value = v
  const newData = random.getPageUser(
      page.value,
      size.value,
  )
  data.value = newData.data
  total.value = total.value
}
</script>
<template>
  <div>
    <zdp_table1
        :columns="columns"
        :data="data"
    />
    <zdp_page1
        :page="page"
        :size="size"
        :total="total"
        @change="onChangePage"
    />
  </div>
</template>

此时, 界面就会随着分页的变化而动态变化了.

在这里插入图片描述

总结

现在我们已经实现了一个基本的分页组件, 这个分页组件可以监听分页的点击事件, 动态的根据分页请求后端的数据.

虽然我们现在是模拟的, 但是当我们接入后端数据的那一刻, 会发现一切都是如此的简单.

那么接下来要继续开发什么呢?

我们还缺什么?

我们缺一个插槽的功能, 这个插槽应该能够实现操作相关的东西, 比如删除用户, 编辑用户等等, 用户也可以自定义扩展这个插槽, 实现自己的逻辑.

那么, 让我们继续开搞吧!!!


http://www.kler.cn/a/459487.html

相关文章:

  • [coredump] 生成管理
  • Spring Boot 各种事务操作实战(自动回滚、手动回滚、部分回滚)
  • 【华为OD-E卷 - 最优资源分配 100分(python、java、c++、js、c)】
  • 蓝耘平台使用InstantMesh‌生成高质量的三维网格模型!3D内容创作!小白入门必看!!!
  • 物联网开发利器:基于web的强大的可拖拽组态软件
  • Linux-掉电保护方案
  • 解决PS 撤销卡顿
  • 【 CSS 】sass 扩展语言的安装
  • IPC$远程植入木马
  • 【YashanDB知识库】yasql / as sysdba无法登录
  • Java设置服务器图片
  • Java-36 深入浅出 Spring - IoC容器体系 BeanFactory过程分析 Bean Lazy-Init
  • Spring Boot集成Netty创建一个TCP服务器,接收16进制数据(自定义解码器和编码器)
  • 纯血鸿蒙ArkUI线性布局详解
  • 【Vue 教程】使用 Vite 快速搭建前端工程化
  • Go singleflight库源码分析
  • 2.阿里云flinkselectdb-jar作业
  • 【React】- 跨域PDF预览、下载(改文件名)、打印
  • Flink如何处理迟到数据?
  • Python毕业设计选题:基于Hadoop 的国产电影数据分析与可视化_django+spider
  • C++ 函数式编程Lambda表达式
  • 磁编码器(Magnetic Encoder)
  • 【每日学点鸿蒙知识】Web嵌套滚动体验、拷贝传递 ArrayBuffer异常问题、ObjectLink 的属性传递、构建读取参数
  • 【高阶数据结构】红黑树封装map、set
  • leetcode hot100 tire前缀树
  • go语言中zero框架项目日志收集与配置