vue3组件封装系列-表格及分页-第二弹

news2025/7/6 17:55:29

第二弹来了,不知道有多少人是看过我的第一篇文章的,今天本来是没想更新的,但是现在项目正在验收期准备上线,闲着还不如来发发文。虽然这两天可能会高产,下一次高产就不知道是什么时候了。话不多说,先上图。

在这里插入图片描述

上面就是效果图了,基于vue3+element-plus觉得还行的可以继续看下去

源码

src\components\MTable\index.vue

<template>
    <div class="table-list-root">
        <el-table
            ref="mtable"
            v-loading="loading"
            v-bind="$attrs"
            :border="border"
            :header-row-style="defaultHeaderRowStyle"
            :header-cell-style="defaultHeaderCellStyle"
            :cell-style="defaultCellStyle"
            class="table-list__main"
        >
            <template #empty>
                <el-empty description="暂无数据" />
            </template>
            <el-table-column v-for="filed in columns" :key="filed.prop" v-bind="filed">
           		 <template #header="{ $index}">
                    <slot :name="`header-${filed.prop}`" :column="filed" :index="$index">
                        {{filed.label}}
                    </slot>
                </template>
                <template v-if="filed.prop && $slots[filed.prop]" #default="scope">
                    <slot :name="filed.prop" :row="scope.row" />
                </template>
            </el-table-column>
        </el-table>
        <div v-if="pagination" class="table-list__footer">
            <el-pagination
                v-bind="paginationProps"
                @current-change="handleCurrentChange"
                @size-change="handleSizeChange"
            />
        </div>
    </div>
</template>
<script setup lang="ts">
import { type PropType, ref, toRefs } from 'vue';
import useTable from './uses/useTable';
import usePagination from './uses/usePagination';
defineOptions({
    inheritAttrs: false
});
type filed = {
    prop?: string;
    [propName: string]: any;
};
const props = defineProps({
    loading: {
        type: Boolean,
        default: false
    },
    // 表格列
    columns: {
        type: Array as PropType<filed[]>,
        default: () => []
    },
    border: {
        type: Boolean,
        default: true
    },
    pagination: {
        type: Object,
        default: () => null
    }
});
// 这里其实可以使用defineModel,我这样写只是为了让习惯vue2的稍微清晰一点
const emit = defineEmits(['update:pagination']);
const mtable = ref(null);
const { pagination } = toRefs(props);

const { defaultHeaderRowStyle, defaultHeaderCellStyle, defaultCellStyle } = useTable();
const { paginationProps, handleSizeChange, handleCurrentChange } = usePagination(emit, pagination);
</script>

src\components\MTable\uses\useTable.ts

这个文件其实就是一些自定义样式,不想分开写的也可以写在一起

import { ref } from 'vue';

export default function useTable() {
  const defaultHeaderRowStyle = ref({
    borderRadius: '4px 4px 0px 0px',
    backgroundColor: '#F8F8F8',
    padding: '0',
    height: '54px',
    lineHeight: '54px',
  });
  const defaultHeaderCellStyle = ref({
    backgroundColor: '#F8F8F8',
    color: '#282828',
    fontSize: '14px',
    padding: '0',
    height: '54px',
  });
  const defaultCellStyle = ref({
    color: '#323233',
    fontSize: '14px',
    lineHeight: '20px',
  });
  return {
    defaultHeaderRowStyle,
    defaultHeaderCellStyle,
    defaultCellStyle,
  };
}

src\components\MTable\uses\usePagination.ts

这里是关于分页的处理

import { computed } from 'vue';

export default function usePagination(emit:any, pagination:any) {
  const paginationProps = computed(() => {
    const paginationVal = pagination.value
    return {
      background: true,
      layout: 'prev, pager, next, sizes, jumper',
      currentPage: paginationVal.page,
      pageSize: paginationVal.size,
      ...paginationVal,
    }
  });

  const handleSizeChange = (pageSize:number | string) => {
    emit('update:pagination', {
      ...pagination.value,
      size: pageSize,
    });
  };
  const handleCurrentChange = (currentPage:number | string) => {
    emit('update:pagination', {
      ...pagination.value,
      page: currentPage,
    });
  };

  return {
    paginationProps,
    handleSizeChange,
    handleCurrentChange,
  };
}

关于组件的源码其实就这些了,下面简单写个使用示例

<template>
<MTable
    v-model:pagination="pagination"
    :loading="loading.tableLoading"
    :data="tableData"
    :columns="TABLECOLUMN"
    @update:pagination="getTableData"
>
 <template #header-sent_staff="{column, index}">
        自定义成员列表头
    </template>
    <template #sent_staff="{ row }">
        自定义成员列xxxxxx
    </template>
    <template #action="{ row }">
        <el-button type="primary" link>预览</el-button>
        <el-button type="primary" link>删除</el-button>
        <el-button type="primary" link>再次发送</el-button>
    </template>
</YzTable>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import MTable from '@/components/MTable/index.vue';
const searchQuery = ref({});
const pagination = ref({
    page: 1,
    size: 10,
    total: 0
});
const tableData = ref([]);
const loading = ref({
    tableLoading: false,
});

onMounted(() => {
    handleQuery();
});

// 点击查询
const handleQuery = async () => {
    pagination.value.page = 1;
    await getTableData();
};

// 请求表格数据
const getTableData = async () => {
    const dataValue = {
        ...searchQuery.value,
        page: pagination.value.page,
        page_size: pagination.value.size
    };
    loading.value.tableLoading = true;
    try {
        const data = await xxxxxxxx(dataValue);
        tableData.value = data.data;
        pagination.value.total = data.total;
    } finally {
        loading.value.tableLoading = false;
    }
};

const TABLECOLUMN = [
    {
        label: '序号',
        type: 'index',
        width: 70
    },
    {
        label: '计划名称',
        prop: 'name'
    },
    {
        label: '发送类型',
        prop: 'send_type',
        formatter: (row: any) => planSendType[row.send_type]
    },
    {
        label: '发送时间',
        prop: 'send_time',
        minWidth: 130,
        formatter: (row: any) => Moment.format(Number(row.send_time))
    },
    {
        label: '创建人',
        prop: 'creator.name'
    },
    {
        label: '所属部门',
        prop: 'creator',
        formatter: (row: any) => row.creator?.department?.name || '-'
    },
    {
        label: '已发送成员',
        prop: 'sent_staff'
    },
    {
        label: '未发送成员',
        prop: 'unsent_staff'
    },
    {
        label: '已送达客户',
        prop: 'delivered'
    },
    {
        label: '未送达客户',
        prop: 'not_delivered'
    },
    {
        label: '创建时间',
        prop: 'created_at',
        minWidth: 130,
        formatter: (row: any) => Moment.format(Number(row.created_at))
    },
    {
        label: '状态',
        prop: 'plan_status',
        formatter: (row: any) => planStatusType[row.plan_status]
    },
    {
        label: '操作',
        prop: 'action',
        fixed: 'right',
        width: 250
    }
];
</script>

看过上一版的朋友们想必都知道上一版的缺陷,内法自定义表头,这次这个版本优化了这个问题,对比上一版能很明显看出我添加了哪一部分,其实很简单的一步操作,很早之前就有了解决方案,但是近期才有时间来更新一下文档

这一期写到这里也就差不多了,有什么意见建议的欢迎提出。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2077870.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenGuass under Ubuntu_22.04 install tutorial

今天开始短学期课程&#xff1a;数据库课程设计。今天9点左右在SL1108开课&#xff0c;听陈老师讲授了本次短学期课程的要求以及任务安排&#xff0c;随后讲解了国产数据库的三层架构的逻辑。配置了大半天才弄好&#xff0c;放一张成功的图片&#xff0c;下面开始记录成功的步骤…

数据融合的超速引擎——SeaTunnel

概览 SeaTunnel是一个由Apache软件基金会孵化的数据集成工具&#xff0c;专为应对大规模数据的快速处理而设计。它以高效的数据处理能力和简洁的架构&#xff0c;帮助企业在数据仓库构建、实时数据处理和数据迁移等场景下&#xff0c;实现数据流的无缝整合。SeaTunnel的设计理…

LDO工作原理与仿真

LDO工作原理与仿真 目录 LDO工作原理与仿真一、LDO内部电路组成1. 基准电压源&#xff08;Reference Voltage Source&#xff09;2. 误差放大器&#xff08;Error Amplifier&#xff09;3. 功率调整元件&#xff08;Power Adjustment Element&#xff09;4. 分压取样电路&#…

用于不平衡分类的 Bagging 和随机森林

用于不平衡分类的 Bagging 和随机森林 Bagging 是一种集成算法&#xff0c;它在训练数据集的不同子集上拟合多个模型&#xff0c;然后结合所有模型的预测。 [随机森林]是 bagging 的扩展&#xff0c;它也会随机选择每个数据样本中使用的特征子集。bagging 和随机森林都已被证…

【Word与WPS如何冻结首行首列及窗口】

1.Word如何冻结首行首列及窗口 microsoft word 中锁定表头是一项实用的功能&#xff0c;可让您在滚动文档时保持表头可见。这在处理大型文档或包含大量数据的表格时非常有用。php小编柚子将为您详细介绍 word 锁定表头位置的方法&#xff0c;帮助您轻松掌握这项实用技巧。 1.…

实体书商城小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;小说分类管理&#xff0c;小说信息管理&#xff0c;订单管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;小说信息&#xff0c;小说资讯&#xff0…

Qt_两种创建组件的方式-通过图形化-通过代码

文章目录 一、通过图形化的方式&#xff0c;在界面上创建一个控件&#xff0c;显示hello world1.打开UI设计界⾯2.拖拽控件⾄ ui 界⾯窗⼝并修改内容3.构建并运行 二、通过代码的方式&#xff0c;通过编写代码&#xff0c;在界面上创建控件&#xff0c;显示hello world在Widget…

手撕python之基本数据类型以及变量

​​​​​​1.基础概念 python就是将不同的数据划分成了不同的类型 就像我们生活中的数据有数字、字符等数据一样 小知识点&#xff1a; 注释&#xff1a;# 全体注释&#xff1a;AltF3 取消注释&#xff1a;AltF4 2.数值类型 数值类型概括 数值类型分为三种&#xff…

Cesium 展示——动态洪水淹没效果

文章目录 需求分析1. 引入插件2. 定义变量3. 开始绘制3.1 绘制点3.2 绘制线3.3 绘制面3.4 开始分析(第一种)3.5 开始分析(第二种)3.6 方法调用4. 整体代码其他需求 从低处到高处实现洪水淹没效果 分析 本篇文章对方法进行单独抽离,因此支持拿来即用,注意传参就可 1. …

宠物系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商品信息管理&#xff0c;店主管理&#xff0c;猫狗查询管理&#xff0c;猫狗宠物社区&#xff0c;管理员管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&…

宝塔 出现 请使用正确的入口登录面板

目录 前言1. 问题所示2. 原理分析3. 解决方法 前言 记录实战中所有的问题导向、原理分析以及解决方法 1. 问题所示 在登录宝塔的时候&#xff0c;出现如下问题 请使用正确的入口登录面板 错误原因&#xff1a;当前新安装的已经开启了安全入口登录&#xff0c;新装机器都会随…

使用redis模拟cookie-session,例子:实现验证码功能

目录 在前后端分离架构中不建议使用cookie-session机制实现端状态识别 所以我们可以使用redis来模拟session-cookie机制 下面我们通过实现验证码的功能来举例 第一步&#xff1a;了解前端要我们返回的数据变量名字&#xff0c;变量类型 1.封装code,data成一个result类&…

多模态技术应用场景探析,景联文科技多模态数据测试平台推动多模态大模型技术突破

多模态技术应用场景探析&#xff0c;景联文科技多模态数据测试平台推动多模态大模型技术突破 在大语言模型背景下&#xff0c;多模态技术的发展已成为一个重要趋势。 Sora是OpenAI推出的多模态大模型&#xff0c;具备高级视频生成与编辑功能&#xff0c;支持长视频、多视角、多…

使用OpenCV库来捕获摄像头视频流,并按指定格式保存

今天我们来使用OpenCV库来捕获摄像头视频流&#xff0c;并将其保存为AVI格式的视频文件&#xff0c; 代码的主要功能包括&#xff1a; 初始化摄像头捕获对象。设置视频编解码器和输出文件路径。循环读取视频帧&#xff0c;处理并保存到文件中。显示处理后的视频帧。按下q键退…

Python | 处理海洋2C 数据 | 非标准时间格式

写在前面 最近&#xff0c;师弟在用Python读取某海洋2C数据时&#xff0c;突然冒出一个报错&#xff1a;“时间单位的参考日期无效&#xff0c;当前日期 00:00:00.0”。这让我回想起&#xff0c;似乎在很久很久以前&#xff0c;我处理SMAP和Argo数据时也遇到过类似的问题。为了…

JavaScript 模块化开发:ES6 模块与 CommonJS 的对比与应用

​ ​ 您好&#xff0c;我是程序员小羊&#xff01; 前言 随着前端项目规模的增长&#xff0c;代码组织和管理变得越来越复杂。模块化开发成为解决这一问题的有效手段&#xff0c;能够帮助开发者将代码进行分割、复用和维护。JavaScript 在发展过程中出现了多种模块化规范&…

【精通SDL之----使用PBO异步传输像素数据】

使用PBO异步传输像素数据 前言一、 一些GPU 分配的常用内存对象介绍二、 PBO 传输原理三、 PBO 使用方法 前言 书接上文【精通SDL之----SDL_RenderReadPixels截屏】&#xff0c;SDL_RenderReadPixels在GLES2上是一个非常耗时的操作&#xff0c;因为   1. OpenGL ES 是一个异步…

.NET Razor类库 - 静态资源组件化

1. 找到Razor类库 打开VS2022 文件 - 新建 - 项目 或者 使用 CtrlShiftN 快捷键 输入Razor 搜索 &#xff0c; 选中Razor类库&#xff0c; 点击 下一步2.创建Razor类库项目 输入项目名称 IX.RCL.Front RCL 是 RazorClassLibrary的简称意思 Front 代表前端静态资源的意思 位…

KEIL Stm32 bin文件生成的两种方法以及报错的处理

Keil里生成bin文件的方法有两种&#xff0c;记录如下&#xff0c;以免忘记~ 首先&#xff0c;在Keil主页面&#xff0c;点击如下按钮&#xff0c;打开Options for Target ‘target 1’对话框&#xff0c;并选择User标签页。 其次&#xff0c;通过在 User标签页 设置 “After B…

一种基于 JavaEE 的合同管理系统,用于存储、管理和跟踪合同的软件工具,功能很完善(附源码)

前言 在现代企业管理中&#xff0c;合同管理是一项至关重要的任务。传统的手动管理合同不仅耗时耗力&#xff0c;而且容易出现错误和遗漏&#xff0c;导致合同执行效率低下&#xff0c;甚至面临法律风险。随着业务的不断扩展&#xff0c;越来越多的企业开始寻求一种更为高效、…