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

vue3+elementPlus封装的一体表格

目录结构

在这里插入图片描述

源码

exportOptions.js

export default reactive([{label: '导出本页',key: '1',},{label: '导出全部',key: '2',},
])

index.vue

<template><div class="flex flex-justify-between flex-items-end"><div><el-button-group><slot name="left"></slot><el-dropdown trigger="click" v-if="$attrs.onExport" @command="exportTable"><el-button :size="size">导出<el-icon class="el-icon--right"><arrow-down /></el-icon></el-button><template #dropdown><el-dropdown-menu><el-dropdown-item v-for="item in exportOptions" :command="item.key">{{ item.label }}</el-dropdown-item></el-dropdown-menu></template></el-dropdown><el-dropdown trigger="click" v-if="$attrs.onPrint" @command="printTable"><el-button :size="size">打印<el-icon class="el-icon--right"><arrow-down /></el-icon></el-button><template #dropdown><el-dropdown-menu><el-dropdown-item v-for="item in printOptions" :command="item.key">{{ item.label }}</el-dropdown-item></el-dropdown-menu></template></el-dropdown></el-button-group></div><el-button-group :size="size"><slot name="right"></slot></el-button-group></div><el-table ref="table" :header-cell-style="headerCellStyle" :cell-style="cellStyle" :row-class-name="rowClassName":size="size" :data="data" :[heightProp]="height || maxHeight" :border="border" :row-key="rowKey":empty-text="emptyText" v-loading="loading" :show-summary="showSummary" :summary-method="summaryMethod"tooltip-effect="dark" @row-click="rowClick" @cell-click="cellClick" @select="select" @select-all="selectAll"@selection-change="selectionChange" element-loading-text="拼命加载中" element-loading-background="rgba(0, 0, 0, 0.5)"@row-dblclick="rowDblclick"><el-table-column v-if="showSelection" fixed="left" type="selection" :reserve-selection="reserveSelection" width="40"align="center" :selectable="selecteisDisabled"></el-table-column><el-table-column v-if="showIndex" fixed="left" type="index" label="序号" min-width="50"><template slot-scope="scope">{{ pageSize * (currentPage - 1) + (scope.$index + 1) }}</template></el-table-column><slot name="columns"></slot></el-table><el-pagination class="text-end mt-3" v-if="$attrs.handleCurrentChange || $attrs.onSizeChange" :size="size"@size-change="dataSizeChange" @current-change="handleCurrentChange" :page-sizes="[VITE_APP_DATA_SIZE, 20, 30, 50]":page-size="pageSize" :disabled="total <= 0 || loading" :current-page="currentPage"layout="total, sizes, prev, pager, next, jumper" :total="total"></el-pagination>
</template><script setup>
import { ElButtonGroup, ElButton, ElDropdown, ElTable, ElPagination, ElNotification } from "element-plus";
import { exportExcel } from '@/utils/export-file.js'
import exportOptions from "./exportOptions.js"
import printOptions from "./printOptions.js"
import propsData from "./props.js"const instance = getCurrentInstance();
const props = defineProps(propsData)
const VITE_APP_DATA_SIZE = import.meta.env.VITE_APP_DATA_SIZE;
const emits = defineEmits(['current-change', 'size-change', 'row-click', 'cell-click', 'row-dblclick', 'select', 'select-all', 'selection-change']);const showSelection = computed(() => {return ["select", "selection-change", "select-all"].includes(Object.keys(instance.proxy.$attrs));
})
const heightProp = computed(() => {// 因为elementUI不能 height 和 max-height 同时存在,所以采用动态属性// console.log("height:", props.height, "maxHeight:", props.maxHeight);return props.height ? "height" : "max-height";
})watch(() => props.total, (now) => {if (now === 0) {return}for (let index in exportOptions) {exportOptions[index].disabled = falseprintOptions[index].disabled = false}
})// 翻页
function handleCurrentChange(val) {console.log(`当前页: ${val}`)emits('current-change', val)
}// 页量
function dataSizeChange(val) {console.log(`每页 ${val}`)emits('size-change', val)
}// 点击行
function rowClick(row, column, event) {// console.log(row, column, event);emits("row-click", row, column, event);
}// 点击单元格
function cellClick(row, column, cell, event) {emits("cell-click", row, column, cell, event);
}// 双击行
function rowDblclick(row, column, event) {emits("row-dblclick", row, column, event);
}// 选择数据
function select(selection, row) {// console.log(election, row);emits("select", selection, row);}
// 选择数据
function selectionChange(selection) {// console.log(selection);emits("selection-change", selection);}
// 全选数据
function selectAll(selection) {console.log(selection);emits("select-all", selection);}// 导出表格
function exportTable(command) {if (props.total < 1) {$message.warning('无数据可导')return}if (command === '1' || (command === '2' && props.total < 3000)) {exportingExcel(command)} else {$dialog.warning({content: '导出数据量过大,您可以选择联系开发人员导出',positiveText: '好',negativeText: '不导了',onPositiveClick: () => {window.open(import.meta.env.VITE_DEPARTMENT_SERVICE,'_blank','location=no, status=no, menubar=no')},})}
}
// 执行导出表格
async function exportingExcel(command) {const title = prompt('文件名称:', '表' || '')if (!title) returnconst notify = notification('开始下载', title)const res = await exporting(command)try {if (res.code === 0 && res.total > 0) {const columns = []props.columns.filter((item) => {if (item.key) {columns.push({header: item.title, // header是exceljs能识别的字段key: item.key,})}})if (props.showIndex) {res.rows = res.rows.map((item, index) => {return {index: index + 1,...item,}})}exportExcel(columns, res.rows, title)notification('下载成功', title)}} catch {notification('数据响应失败', title)}try {notify.close()} catch {notify.destroy()}
}
function notification(content, title) {return Notification.permission === 'granted'? new Notification(content, { body: title }): ElNotification.info({ content, meta: title })
}
// 打印表格数据
function printTable(command) {if (props.total < 1) {return $message.info('无数据打印')}emits('printing', command)
}defineExpose({exportExcel
})
</script><style scoped lang="scss">
:deep(.n-data-table-tr .n-data-table-resize-button) {width: 1px;left: unset;right: 0;
}:deep(.n-data-table-tr .n-data-table-resize-button::after) {width: 1px;right: -1px;left: unset;
}
</style>

printOptions.js

export default reactive([{label: '打印本页',key: '1',},{label: '打印全部',key: '2',},
])

props.js

export default {// 显示序号列showIndex: {type: Boolean,default: false,},data: {type: Array,default: () => {return []},},columns: {type: Array,default: () => {return []},},loading: {type: Boolean,default: true,},size: {type: String,default: 'medium',},emptyText: {type: String,default: '暂无数据',},border: {type: Boolean,default: true,},total: {type: Number,default: 0,},pageSize: {type: Number,default: Number(import.meta.env.VITE_APP_DATA_SIZE),},currentPage: {type: Number,default: 0,},height: {type: Number,default: 550,},maxHeight: {type: Number,},headerCellStyle: {type: [Function, Object],},cellStyle: {type: [Function, Object],},// 返回值用来决定这一行的 CheckBox 是否可以勾选selecteisDisabled: {type: Function},rowKey: {type: Function,default: undefined,},showSummary: {type: Boolean,default: false,},summaryMethod: {type: Function},exporting: {type: Function,default: undefined,},
}

使用说明

 <q-table :data="tableData"><template v-slot:left>表头上左侧容器</template><template v-slot:right>表头上右侧容器</template><template v-slot:columns>数据表体部分</template>
</q-table>
  • 参数

    \props.js

  • 事件

    ['current-change', 'size-change', 'row-click', 'cell-click', 'row-dblclick', 'select', 'select-all', 'selection-change']

  • 导出

    传入onExporting事件,就会显示导出摁扭

  • 打印

    传入onPrinting事件,就会显示打印摁扭

  • 选择列

    传入'select', 'select-all', 'selection-change'其中一种事件,就会显示选择列

相关文章:

vue3+elementPlus封装的一体表格

目录结构 源码 exportOptions.js export default reactive([{label: 导出本页,key: 1,},{label: 导出全部,key: 2,}, ])index.vue <template><div class"flex flex-justify-between flex-items-end"><div><el-button-group><slot name…...

Junit5 单元测试入门

基础知识 常用注解含义 Test&#xff1a;标记一个方法为测试方法BeforeEach&#xff1a;标记的方法会在每个测试方法执行前执行AfterEach&#xff1a;标记的方法会在每个测试方法执行后执行BeforeAll&#xff1a;标记的方法会在所有测试方法执行前执行一次AfterAll&#xff1…...

数字信号处理-数学基础

来源哪都有&#xff0c;个人复习使用 一 积分 常用积分公式&#xff1a; 基本积分方法 凑微分法(也称第一换元法)&#xff1a; 换元&#xff1a; 分部积分&#xff1a; 卷积 这里有动图解释&#xff1a; https://mathworld.wolfram.com/Convolution.html 欧拉公式 e i x…...

【Exp】# Microsoft Visual C++ Redistributable 各版本下载地址

Microsoft官方页面 https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads Redistributable 2019 X86: https://aka.ms/vs/16/release/VC_redist.x86.exe X64: https://aka.ms/vs/16/release/VC_redist.x64.exe Redistributable 201…...

Hive 分桶表的创建与填充操作详解

Hive 分桶表的创建与填充操作详解 在 Hive 数据处理中&#xff0c;分桶表是一个极具实用价值的功能&#xff0c;它相较于非分桶表能够实现更高效的采样&#xff0c;并且后续还可能支持诸如 Map 端连接等节省时间的操作。不过&#xff0c;值得注意的是&#xff0c;在向表写入数…...

[小白系列]Ubuntu安装教程-安装prometheus和Grafana

Docker安装prometheus 拉取镜像 docker pull prom/prometheus 配置文件prometheus.yml 在/data/prometheus/建立prometheus.yml配置文件。&#xff08;/data/prometheus/可根据自己需要调整&#xff09; global:scrape_interval: 15s # By default, scrape targets ev…...

Flask使用长连接

Flask使用flask_socketio实现websocket Python中的单例模式 在HTTP通信中&#xff0c;连接复用&#xff08;Connection Reuse&#xff09;是一个重要的概念&#xff0c;它允许客户端和服务器在同一个TCP连接上发送和接收多个HTTP请求/响应&#xff0c;而不是为每个新的请求/响…...

数据分析思维案例:游戏评分低,怎么办?

【面试题】 某款手游在应用市场评分相比同类型游戏处于劣势。 请分析可能的原因并给出相关建议。 【分析思路】 一、明确问题 1. 明确业务指标 定义&#xff1a;应用市场评分一般指某一应用在某个应用市场上线以来的总体平均评分。 除“总体平均评分”以外&#xff0c;部分应用…...

【学习总结|DAY012】Javabean书写练习

一、主要代码 public class Phone {public Phone() {}public Phone(String brand, int price, String color) {this.brand brand;this.price price;this.color color;}String brand;int price;String color;public String getBrand() {return brand;}public void setBrand(…...

Mac环境下brew安装LNMP

安装不同版本PHP 在Mac环境下同时运行多个版本的PHP&#xff0c;同Linux环境一样&#xff0c;都是将后台运行的php-fpm设置为不同的端口号&#xff0c;下面将已php7.2 和 php7.4为例 添加 tap 目的&#xff1a;homebrew仅保留最近的php版本&#xff0c;可能没有你需要的版本…...

openEuler 知:安装系统

文章目录 前言图形化安装文本方式安装 前言 本文只介绍安装过程中需要特别注意的地方&#xff0c;常规的内容需要参考其它文档。 图形化安装 自定义分区&#xff1a; 说明&#xff1a;anaconda 默认分区&#xff0c;在 OSNAME.conf 中进行了配置&#xff0c;openEuler 默认根…...

Zephyr 入门-设备树与设备驱动模型

学习链接&#xff1a;https://www.bilibili.com/video/BV1L94y1F7qS/?spm_id_from333.337.search-card.all.click&vd_source031c58084cf824f3b16987292f60ed3c 讲解清晰&#xff0c;逻辑清楚。 1. 设备树概述&#xff08;语法&#xff0c;如何配置硬件&#xff0c;c代码如…...

点云标注软件SUSTechPOINTS的安装和使用,自测win10和ubuntu20.04下都可以用

点云标注软件SUSTechPOINTS的安装和使用 github项目源码&#xff1a;https://github.com/naurril/SUSTechPOINTS gitee源码以及使用教程&#xff1a;https://gitee.com/cuge1995/SUSTechPOINTS 首先拉取源码 git clone https://github.com/naurril/SUSTechPOINTS最好是在cond…...

etcd资源超额

集群内apiserver一直重启&#xff0c;重启kubelet服务后查看日志发现一下报错&#xff1a; Error from server: etcdserver: mvcc: database space exceeded 报错原因&#xff1a; etcd服务未设置自动压缩参数&#xff08;auto-compact&#xff09; etcd 默认不会自动 compa…...

AndroidStudio-常见界面控件

一、Button package com.example.review01import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import android.widget.TextViewclass Review01Activity : AppCompatActivity() {override fun onCreate(savedInstanceStat…...

网络协议(TCP/IP模型)

目录 网络初识 网络协议 协议分层 协议拆分 分层 协议分层的优势 1.封装效果 2.解耦合 TCP/IP五层模型 协议之间配合工作&#xff08;详解&#xff09; 网络初识 网络核心概念&#xff1a; 局域网&#xff1a;若干电脑连接在一起&#xff0c;通过路由器进行组网。 …...

python 清华pip镜像源报HTTP error 403

报错信息 ERROR: HTTP error 403 while getting https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/52/79/a64937a2185b91a96cc5406e3ea58120980c725543d047e112fb3084a972/fake_useragent-2.0.0-py3-none-any.whl (from https://mirrors.tuna.tsinghua.edu.cn/pypi/we…...

swift 屏幕录制

步骤 1&#xff1a;导入 ReplayKit import ReplayKit步骤 2&#xff1a;开始录屏 let screenRecorder RPScreenRecorder.shared() // 麦克风或系统音频 screenRecorder.isMicrophoneEnabled truefunc startRecording() {guard screenRecorder.isAvailable else {print(&quo…...

通过精密时间协议(PTP)对计算机网络中的多个设备进行时间同步

PTP 模块 - 使用教程 目录 PTP 模块 - 使用教程简介第 1 步&#xff1a;为主时钟创建一个 PTP 时钟实例第 2 步&#xff1a;添加 PTP 端口第 3 步&#xff1a;查询 PTP 时钟或 PTP 端口的状态第 4 步&#xff1a;清除 FAULTY 状态第 5 步&#xff1a;为 PTP 事件安装处理程序第…...

Docker 安装系列

Centos8 安装Docker Docker安装mysql8.0 Docker安装稳定版本nginx-1.26.2 Docker 安装最新版本 Jenkins Docker Redis Docker 安装 eclipse-mosquitto Docker mongo:5.0 Docker 安装 Redis的完全体版本RedisMod docker pull elasticsearch:8.0.0 docker 安装nacos v2.…...

福特押注五款新车型,含电动车与Bronco,欲重振欧洲市场

福特计划未来三年内在欧洲推出五款全新乘用车&#xff0c;以重振其在欧洲市场日渐式微的品牌形象。这一"福特欧洲乘用车新纪元"计划涵盖一款全新的多能源Bronco SUV、一款小型纯电掀背车、一款纯电SUV&#xff0c;以及两款多能源跨界SUV&#xff0c;所有车型均专为欧…...

异构多核处理器如何实现安卓、Linux与RTOS的原生融合?

1. 项目概述&#xff1a;一颗“三栖”处理器的诞生最近在嵌入式圈子和一些硬件开发者社区里&#xff0c;一个话题的热度悄然攀升&#xff1a;一颗号称能同时原生运行安卓、Linux和RTOS的国产CPU。这听起来有点像是“瑞士军刀”式的处理器&#xff0c;试图用一个硬件平台覆盖从消…...

加速3DGS生成与数字孪生开发:不可错过的8款效率工具盘点

一、行业核心技术科普&#xff1a;3DGS数字孪生开发的工具链概览一个高效的3DGS数字孪生开发流程&#xff0c;离不开一套完整的工具链。从数据采集、模型生成、格式优化到应用开发与部署&#xff0c;每个环节都有其专用的工具。其域创新围绕“感知—重建—理解—创造”的技术路…...

从‘拍脑袋’到‘有框架’:我是如何用MECE给团队Bug根因分析会‘降噪’的

从‘拍脑袋’到‘有框架’&#xff1a;我是如何用MECE给团队Bug根因分析会‘降噪’的 作为技术团队的负责人&#xff0c;你是否经历过这样的场景&#xff1a;Bug复盘会上&#xff0c;大家七嘴八舌地讨论着"测试没覆盖到"、"代码写得有问题"、"需求理解…...

LeetCode 每日一题笔记 日期:2026.05.19 题目:2540. 最小公共值

LeetCode 每日一题笔记 0. 前言 日期&#xff1a;2026.05.19题目&#xff1a;2540. 最小公共值难度&#xff1a;简单标签&#xff1a;数组、双指针、哈希表 1. 题目理解 问题描述&#xff1a; 给定两个按非降序排序的整数数组 nums1 和 nums2&#xff0c;请返回它们的最小公共整…...

别再纠结选哪种了!一文讲透无人机测深三剑客(激光雷达/测深仪/GPR)的实战选型指南

无人机测深技术三剑客&#xff1a;激光雷达、测深仪与探地雷达的深度选型指南 当无人机遇上水深测量&#xff0c;技术选型往往成为项目成败的关键。在河道整治、水库清淤、海岸线测绘等场景中&#xff0c;工程师们常面临一个核心难题&#xff1a;如何在激光雷达、测深仪和探地雷…...

从设计到验证:如何用ADS的HB2TonePAE_FPswp模板快速评估你的PA线性度?

射频功放线性度评估实战&#xff1a;ADS高级仿真模板深度解析 在射频功率放大器(PA)的设计流程中&#xff0c;线性度评估往往是最耗时的环节之一。传统方法需要工程师手动搭建测试平台&#xff0c;不仅效率低下&#xff0c;还容易引入人为误差。Keysight ADS软件内置的HB2ToneP…...

嵌入式操作系统选型实战指南:从硬件约束到商业考量的五维决策框架

1. 项目概述&#xff1a;一个困扰无数工程师的经典难题干了十几年嵌入式&#xff0c;从8位单片机玩到多核ARM&#xff0c;从裸机撸到各种RTOS&#xff0c;再到Linux、Android&#xff0c;最常被问到也最头疼的问题之一就是&#xff1a;“老大&#xff0c;新项目用哪个操作系统好…...

DCNv4:重塑视觉模型核心,三倍速率的动态稀疏卷积如何炼成?

1. 从标准卷积到DCNv4的进化之路 计算机视觉领域的核心算子就像乐高积木里的基础模块&#xff0c;决定了整个模型的表达能力。传统卷积就像用固定形状的积木拼图&#xff0c;虽然稳定但缺乏灵活性。2017年诞生的可变形卷积&#xff08;DCN&#xff09;首次给积木加上了"可…...

SAP PP实战指南:从零到一掌握BOM创建、群组BOM配置与CS01核心操作

1. BOM基础概念与核心价值 物料清单&#xff08;Bill of Materials&#xff0c;简称BOM&#xff09;是制造业的DNA图谱&#xff0c;它用结构化数据描述产品从原材料到成品的完整演化路径。我第一次接触SAP PP模块时&#xff0c;项目经理指着屏幕上的BOM结构说&#xff1a;"…...