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

news2024/11/17 21:29:20

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

在这里插入图片描述

上面就是效果图了,基于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 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 #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>

以上只是简单的示例,如果结合我上一篇文章,那么整个列表页面,除了表格顶部那些个操作按钮,就全部都是数据驱动了,至于按钮那一块的封装,过于简单,并不准备放出来,如果需要的话可以留言。

还是老样子,除了那几个固定的key必须,其他都不是必须的,并且支持全部table的属性,目前的缺陷是无法自定义表格header,这个目前还没有好的解决方案。总体来说够用了,那种有header定制的也不多,或者整个项目都差不多,可以直接写在组件里面

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

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

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

相关文章

python实现钉钉通讯录导出Excel表

Python工具开源专栏 Py0004 python实现钉钉通讯录导出Excel表 Python工具开源专栏前言目录结构部分演示完整代码已在GitHub上开源 前言 需求来源于公司&#xff0c;需要将钉钉通讯录以Excel表的形式导出到本地&#xff0c;方便定期备份。导出的Excel需要处理钉钉用户兼任多部门…

【计算机毕业设计】药品销售系统产品功能介绍——后附源码

&#x1f389;**欢迎来到我的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 一名来自世界500强的资深程序媛&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 在深度学习任务中展现出卓越的能力&#xff0c;包括但不限于…

华为数通HCIA ——企业网络架构以及产品线

一.学习目标&#xff1a;精讲网络技术&#xff0c;可以独立搭建和维护中小企业网络&#xff01; 模拟器&#xff08;华为方向请安装ENSP&#xff0c;Ensp-Lite已有安装包&#xff0c;号称功能更加完善-这意味着要耗费更多的系统资源但是仅对华为内部伙伴申请后方可使用&#x…

TDengine高可用架构之TDengine+Keepalived

之前在《TDengine高可用探讨》提到过&#xff0c;TDengine通过多副本和多节点能够保证数据库集群的高可用。单对于应用端来说&#xff0c;如果使用原生连接方式&#xff08;taosc&#xff09;还好&#xff0c;当一个节点下线&#xff0c;应用不会受到影响&#xff1b;但如果使用…

Python 基础、流程、容器、函数

一、基础语法 1.1 前言 1.1.1 Python简介 Python是一门编程语言&#xff0c;Python的作者是Guido van Rossum&#xff08;龟叔&#xff09; Python优点&#xff1a;简单易学 Python与嵌入式、集成电路行业 强大的库和工具生态系统&#xff1a;Python拥有广泛而强大的库和…

【Harmony3.1/4.0】笔记五

概念 本文综合row&#xff0c;column作为主要布局&#xff0c;结合image组件&#xff0c;text组件&#xff0c;textimput组件&#xff0c;button组件以及轮播布局搭建登录页面 效果图 ArkTS代码 //登录综合页面 Entry Component struct Five{//添加图片State imgs:Resource[…

网络安全主题纪录片

网络安全主题纪录片 文章目录 网络安全主题纪录片第四公民黑客帝国系列龙纹身女孩碟中谍系列虎胆龙威4匿名者终结者2&#xff1a;审判日东方快车谋杀案黑客国家公敌我是谁&#xff1a;没有绝对安全的系统黑客军团速度与激情系列十亿美元大劫案勒索软件的背后黑客的恐惧为什么网…

共享汽车管理|基于SprinBoot+vue的共享汽车管理系统(源码+数据库+文档)

共享汽车管理目录 基于SprinBootvue的共享汽车管理系统 一、前言 二、系统设计 三、系统功能设计 1 管理员模块的实现 1.1 用户信息管理 1.2 投放地区管理 1.3 汽车信息管理 1.4 汽车入库管理 2 用户模块的实现 2.1 汽车投放 2.2 使用订单管理 2.3 汽车归还 四、…

Java八股文4-Linux篇

Linux篇 Linux中常见命令&#xff1a;Linux常见命令 1.free命令-查看内存状态 free命令用于显示内存状态&#xff0c;它可以提供关于系统内存使用情况的详细信息。这个命令会显示出内存的使用情况&#xff0c;包括实体内存、虚拟的交换文件内存、共享内存区段&#xff0c;以及…

开发简易复用 SDK(项目加分项)

文章目录 开发 SDK新建项目修改pom文件删除启动类创建配置类复制之前的客户端新建spring.factories打包 开发 SDK 为什么要开发SDK。 减少代码的冗余提高代码的复用 如果实际项目中需要使用到该SDK&#xff0c;在pom.xml中注入就可以了。 类似于maven一样&#xff0c;把需要…

`THREE.AudioAnalyser` 音频分析

demo案例 THREE.AudioAnalyser 音频分析 入参 (Input Parameters): audio: 一个 THREE.Audio 实例&#xff0c;代表要分析的音频。fftSize: 快速傅里叶变换&#xff08;FFT&#xff09;的大小&#xff0c;用于确定分析的精度和频率分辨率。smoothingTimeConstant: 平滑时间…

AI时代的GPU集群网络算力分析

浅谈GPU集群网络、集群规模和集群算力 引言在生成式AI&#xff08;GenAI&#xff09;和大模型时代&#xff0c;不仅需要关注单个GPU卡的算力&#xff0c;更要关注GPU集群的总有效算力。单个GPU卡的有效算力可以通过该卡的峰值算力来测算&#xff0c;例如&#xff0c;对于Nvidia…

【01-机器学习入门:理解Scikit-learn与Python的关系】

文章目录 前言Python与机器学习Scikit-learn简介Scikit-learn与Python的关系使用Scikit-learn进行机器学习结语前言 在当今的数据科学和人工智能领域,机器学习已经成为了一个不可或缺的组成部分。而对于那些刚刚踏入这一领域的新手来说,理解机器学习的基本概念和找到合适的工…

UDS报文传输的四种帧

ISO14229-1规定了26个诊断服务细节&#xff0c;也就是UDS诊断报文的细节。它只规定了各个服务每个字节的含义&#xff0c;它不关心底层到底是怎么传输的。 ISO15765-2规定了基于CAN总线进行UDS报文传输的细节&#xff08;包括四种帧&#xff09;。是在CAN总线传输的情况下&…

Vitis HLS 学习笔记--对于启动时间间隔(II)的理解

目录 1. II的重要性 2. 案例分析 3. 总结 1. II的重要性 在Vitis HLS&#xff08;High-Level Synthesis&#xff09;中&#xff0c;启动时间间隔&#xff08;II&#xff0c;Iteration Interval&#xff09;是一个非常关键的概念&#xff0c;对于实现高性能的硬件加速器设计…

SpanBert学习

SpanBERT: Improving Pre-training by Representing and Predicting Spans 核心点 提出了更好的 Span Mask 方案&#xff0c;也再次展示了随机遮盖连续一段字要比随机遮盖掉分散字好&#xff1b;通过加入 Span Boundary Objective (SBO) 训练目标&#xff0c;增强了 BERT 的性…

蓄能勃发,酷开科技携酷开系统“软硬结合”提升大屏实力

智慧大屏以全新媒体形态之姿在过去几年快速增长&#xff0c;截至去年上半年&#xff0c;国内联网电视总量覆盖达5.26亿&#xff0c;其中智能电视终端活跃量达3.22亿&#xff0c;在PC、Mobile流量增长已显疲态的背景下&#xff0c;大屏的高速发展意味着一个新的赛道的崛起&#…

程序员英语之Spring篇

spring.io/quickstart 本期课程讲解Spring官网的快速上手页面 官网地址 https://spring.io/quickstart Spring Quickstart Guide Spring 快速开始指南 Guide 指南 What you’ll build 接下来你将要构建的是什么&#xff1f; build 构建 You will build a classic “H…

Sectigo证书申请流程及价格介绍

Sectigo 是一家全球知名的数字证书颁发机构&#xff08;Certificate Authority, CA&#xff09;&#xff0c;自1998年起就开始提供 SSL 证书服务&#xff0c;是全球最早的 CA 机构之一。 一 Sectigo证书申请流程 1 确定证书类型 根据自身的需求确定证书的类型&#xff0c;一…

from_pretrained明明以及下载好模型,却突然不能加载了报错

本人报错&#xff1a;OSError: Error no file named model_index.json found in directory /home/xxx/我的python学习/textToImage/sdxl-turbo. 原因&#xff1a;路径错误导致无法加载模型的配置文件 pipe AutoPipelineForText2Image.from_pretrained("stabilityai/sdx…