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

【ElementPlus】在Vue3中实现表格组件封装

预览

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/2a954e6b844947f8a7a3e7f30d39421e.pn

搜索筛选组件

<template><div><el-formref="formView":model="formData"label-width="auto"label-position="right":label-col-style="{ 'min-width': '100px' }":inline="true"><el-form-item :prop="column.prop" :label="column.label" v-for="column in columns" :key="column.prop"><slot :name="column.prop" :query="formData"><el-input v-model="formData[column.prop]" :placeholder="`请输入${column.label}`" clearable /></slot></el-form-item><el-form-item><el-button type="primary" icon="Search" @click="onSubmit">查询</el-button><el-button icon="Refresh" @click="onReset">重置</el-button></el-form-item><div class="mb15"><slot name="handleMenu" /></div></el-form></div>
</template>
<script setup>
import { ref, toRaw, watch, onMounted } from "vue"const props = defineProps(["columns"])
const emit = defineEmits(["change", "submit", "reset"])
const formView = ref(null)
let formData = ref()
let isReset = false
watch(() => formData,(data) => {if (isReset) {isReset = falsereturn}emit("change", toRaw(data.value))},{ deep: true, immediate: true }
)onMounted(() => {formData.value = columnsToFormData()
})
function onSubmit() {emit("submit", toRaw(formData.value))
}function onReset() {isReset = trueformData.value = columnsToFormData()emit("reset", toRaw(formData.value))
}function columnsToFormData() {return Object.fromEntries([].concat(...props.columns.map((item) => {if (item.items) {return item.items.map((iItem) => [iItem.prop, item?.defaultValue || null])}return [[item.prop, item?.defaultValue || null]]})))
}
</script>

表格组件

<template><div><!-- 筛选条件相关 --><query-header :columns="queryColumns" @change="onQueryParamsChange" @submit="onSubmit" @reset="onReset"><template v-for="item in queryColumns" :key="item.prop" v-slot:[item.prop]="{ query }"><slot :name="`${item.prop}Query`" :query="query" /></template><template #handleMenu><slot name="handleMenu" /></template></query-header><!-- 表格 --><el-table ref="tableView" :data="list" :loading="loading" @selection-change="onSelectionChange"><!-- 表格选择 --><el-table-column type="selection" width="55" v-if="props.selection" /><!-- 展开行内容 --><el-table-column type="expand" v-if="expand"><template #default="{ row }"><slot name="expand" :row="row" /></template></el-table-column><!-- 表格列 --><el-table-columnv-for="column in tableColumnsList":key="column.prop":align="column.align ? column.align : 'center'":label="column.label":prop="column.prop":width="column.width":sortable="column.sortable"show-overflow-tooltip><template #default="scope"><slot :name="column.prop" :row="scope.row">{{ scope.row[column.prop] }}</slot></template></el-table-column><!-- 操作菜单 --><slot name="tableMenu" /></el-table></div><!-- 分页 --><el-paginationv-model:current-page="queryForm.page_no"v-model:page-size="queryForm.page_size":page-sizes="[1, 10, 20, 50, 100]"background:background="background"layout="total, sizes, prev, pager, next, jumper":total="total"@size-change="onPageSizeChange"@current-change="onPageChange"class="mt20 flex"style="justify-content: flex-end"/>
</template>
<script setup>
import request from "@/utils/request"
import QueryHeader from "./QueryHeader.vue"
import { ref, reactive, onMounted, watch } from "vue"/* 父组件传递参数apiUrl: { type: String, required: true },   // 请求地址tableColumns: { type: Array, required: true }, // 表格列selection: { type: Boolean, default: false }, // 是否可多选rowKey: { type: String, default: '' }, // 行数据的 Key,用来优化 Table 的渲染;expand: { type: Boolean, default: false }, // 是否可展开*/
const props = defineProps(["apiUrl", "tableColumns", "expandable", "selection", "rowKey", "expand"])const tableView = ref(null)
const queryColumns = ref([])
const tableColumnsList = ref([])watch(() => props.tableColumns,(newVal, oldVal) => {queryColumns.value = newVal.filter((item) => {return item.search})tableColumnsList.value = newVal.filter((item) => {return !item.hide})}
)onMounted(() => {queryColumns.value = props.tableColumns.filter((item) => {return item.search})tableColumnsList.value = props.tableColumns.filter((item) => {return !item.hide})getList()
})/* 获取列表数据 */
const loading = ref(false)
const total = ref(0)
const list = ref([])
const queryForm = reactive({page_no: 1,page_size: 10,
})
function getList() {loading.value = truelet params = JSON.parse(JSON.stringify(queryForm))request.get({url: props.apiUrl,params,}).then((res) => {list.value = res.liststotal.value = res.countloading.value = false})
}
/*  */
/* 表格分页页数切换 */
function onPageChange(num) {queryForm.page_no = numgetList()
}
/* 表格每页数量切换 */
function onPageSizeChange(num) {queryForm.page_size = numqueryForm.page_no = 1getList()
}/* 重置查询 */
function queryList(dataList) {/* dataList除query-header 外查询参数 */if (dataList && dataList.length > 0) {for (let item of dataList) {queryForm[item.key] = item.value}}queryForm.page_no = 1getList()
}
/* 表格选择 */
const emit = defineEmits(["select"])
function onSelectionChange(value) {emit("select", value)
}
/* 查询条件-点击查询按钮 */
function onSubmit() {queryList()
}
/* 查询条件-参数变化 */
function onQueryParamsChange(value) {Object.assign(queryForm, value)
}
/*  查询条件-清空参数 */
function onReset(value) {Object.assign(queryForm, value)queryList()
}
/* 暴露到父组件方法 */
defineExpose({queryList,
})
</script>

页面引用

<template><div class="app-container home"><query-table ref="tableViewRef" apiUrl="/adviser/lists" :table-columns="tableColumns" :selection="true"><!-- 筛选条件自定义 --><template #create_timeQuery="{ query }"><el-date-pickerv-model="query.create_time"type="daterange"value-format="YYYY-MM-DD"range-separator="-"start-placeholder="开始日期"end-placeholder="结束日期"@change="onTimeChange"/></template><template #is_disableQuery="{ query }"><el-select v-model="query.is_disable" clearable><el-option label="是" :value="1"></el-option><el-option label="否" :value="0"></el-option></el-select></template><template #handleMenu><el-row><el-col :span="12"><el-space><el-button type="primary" icon="Plus" @click="clickAdd('')" v-perms="['adviser/add']">添加</el-button><el-button>批量导入</el-button><el-button>批量导出</el-button></el-space></el-col></el-row></template><!-- table自定义列 --><template #is_disable="{ row }"><el-switch v-model="row.is_disable" :active-value="1" :inactive-value="0"></el-switch></template><template #tableMenu><el-table-column label="操作" align="center" width="200"><template #default="{ row }"><router-link :to="`./info?id=${row.id}`"><el-button type="primary" link>详情</el-button></router-link><!-- <el-button v-perms="['adviser/edit']" type="primary" link @click="clickAdd(row.id)">编辑</el-button><el-button v-perms="['adviser/delete']" type="danger" link @click="handleDelete(row.id)">删除</el-button> --></template></el-table-column></template></query-table></div>
</template><script setup name="Index">
import QueryTable from "@/components/QueryTable/index.vue"const tableColumns = [{ label: "顾问名称", prop: "name", search: true },{ label: "手机号", prop: "mobile", search: true },{ label: "微信号", prop: "user_id" },{ label: "关联用户数", prop: "adviser_id", width: 150 },{ label: "当前面试", prop: "commission", sortable: true },{ label: "预约单", prop: "w_commission", sortable: true },{ label: "服务单", prop: "wz_commission", sortable: true },{ label: "创建时间", prop: "create_time", width: 160, search: true },{ label: "是否启用", prop: "is_disable", search: true },
]
</script><style scoped lang="scss"></style>

相关文章:

【ElementPlus】在Vue3中实现表格组件封装

预览 搜索筛选组件 <template><div><el-formref"formView":model"formData"label-width"auto"label-position"right":label-col-style"{ min-width: 100px }":inline"true"><el-form-item …...

cursor重构谷粒商城04——vagrant技术快速部署虚拟机

前言&#xff1a;这个系列将使用最前沿的cursor作为辅助编程工具&#xff0c;来快速开发一些基础的编程项目。目的是为了在真实项目中&#xff0c;帮助初级程序员快速进阶&#xff0c;以最快的速度&#xff0c;效率&#xff0c;快速进阶到中高阶程序员。 本项目将基于谷粒商城…...

26、正则表达式

目录 一. 匹配字符 .&#xff1a;匹配除换行符外的任意单个字符。 二. 位置锚点 ^&#xff1a;匹配输入字符串的开始位置。 $&#xff1a;匹配输入字符串的结束位置。 \b&#xff1a;匹配单词边界。 \B&#xff1a;匹配非单词边界。 三. 重复限定符 *&#xff1a;匹配…...

SpringBoot使用MockMVC通过http请求controller控制器调用测试

说明 在Spring Boot中编写测试控制器调用是一个常见的需求,通常使用Spring的测试框架来完成。Spring Boot提供了多种方式来测试控制器,包括使用MockMvc进行模拟HTTP请求和响应的测试。 基本示例 1. 创建Spring Boot项目 首先,确保你已经创建了一个Spring Boot项目。如果…...

【Unity3D】Unity混淆工具Obfuscator使用

目录 一、导入工具 二、各种混淆形式介绍 2.1 程序集混淆 2.2 命名空间混淆 2.3 类混淆 2.4 函数混淆 2.5 参数混淆 2.6 字段混淆 2.7 属性混淆 2.8 事件混淆 三、安全混淆 四、兼容性处理 4.1 动画方法兼容 4.2 GUI方法兼容 4.3 协程方法兼容 五、选项 5.1 调…...

C语言语法基础学习—动态分配空间(new和malloc的用法及区别)

前言 在 C 语言中&#xff0c;动态内存分配主要是通过 malloc() 和 free() 函数来完成的。而在 C 中是使用new和delete关键字&#xff0c;来动态分配内存。 虽然 C 语言没有 new&#xff0c;但 malloc() 和 new 在内存分配上的作用是相似的。下面我们详细解释 malloc() 和 ne…...

QT:控件属性及常用控件(3)-----输入类控件(正则表达式)

输入类控件既可以进行显示&#xff0c;也能让用户输入一些内容&#xff01; 文章目录 1.Line Edit1.1 用户输入个人信息1.2 基于正则表达式的文本限制1.3 验证两次输入的密码是否一致1.4 让输入的密码可以被查看 2.Text Edit2.1 输入和显示同步2.1 其他信号出发情况 3.ComboBox…...

Hive SQL 执行计划解析

Hive SQL 执行计划解析 一、 explain用法 1. SQL 查询 EXPLAIN SELECT SUM(view_dsp) AS view_sum FROM ads.table_a WHERE p_day 2025-01-06;2. 执行计划 STAGE DEPENDENCIES:Stage-1 is a root stageStage-0 depends on stages: Stage-1STAGE PLANS:Stage: Stage-1Map …...

热更新杂乱记

热更新主要有一个文件的MD5值的比对过程&#xff0c;期间遇到2个问题&#xff0c;解决起来花费了一点时间 1. png 和 plist 生成zip的时候再生成MD5值会发生变动。 这个问题解决起来有2种方案&#xff1a; &#xff08;1&#xff09;.第一个方案是将 png和plist的文件时间改…...

博客搭建 — GitHub Pages 部署

关于 GitHub Pages GitHub Pages 是一项静态站点托管服务&#xff0c;它直接从 GitHub 上的仓库获取 HTML、CSS 和 JavaScript 文件&#xff0c;通过构建过程运行文件&#xff0c;然后发布网站。 本文最终效果是搭建出一个域名为 https://<user>.github.io 的网站 创建…...

翻译:How do I reset my FPGA?

文章目录 背景翻译&#xff1a;How do I reset my FPGA?1、Understanding the flip-flop reset behavior2、Reset methodology3、Use appropriate resets to maximize utilization4、Many options5、About the author 背景 在写博客《复位信号的同步与释放&#xff08;同步复…...

Linux 进程环境变量:深入理解与实践指南

&#x1f31f; 快来参与讨论&#x1f4ac;&#xff0c;点赞&#x1f44d;、收藏⭐、分享&#x1f4e4;&#xff0c;共创活力社区。&#x1f31f; &#x1f6a9;用通俗易懂且不失专业性的文字&#xff0c;讲解计算机领域那些看似枯燥的知识点&#x1f6a9; 在 Linux 系统里…...

Linux探秘坊-------5.git

1.git介绍 1.版本控制器 为了能够更⽅便我们管理这些不同版本的⽂件&#xff0c;便有了版本控制器。所谓的版本控制器&#xff0c;就是能让你了解到⼀个⽂件的历史&#xff0c;以及它的发展过程的系统。通俗的讲就是⼀个可以记录⼯程的每⼀次改动和版本迭代的⼀个管理系统&am…...

Linux中的几个基本指令(二)

文章目录 1、cp指令例一&#xff1a;例二&#xff1a;例三&#xff1a;例四&#xff1a;例五&#xff1a; 2、mv 指令例一&#xff1a;例二&#xff1a; 3、cat指令例一&#xff1a; 4、tac指令5、which指令6、date指令时间戳&#xff1a;7、zip指令 今天我们继续学习Linux下的…...

Java入门笔记(1)

引言 在计算机编程的广袤宇宙中&#xff0c;Java无疑是一颗格外耀眼的恒星。那么&#xff0c;Java究竟是什么呢&#xff1f; Java是美国Sun公司&#xff08;Stanford University Network&#xff09;在1995年推出的一门计算机高级编程语言。曾经辉煌的Sun公司在2009年被Oracle&…...

设计模式的艺术-开闭原则

原则使用频率图&#xff08;仅供参考&#xff09; 1.如何理解开闭原则 简单来说&#xff0c;开闭原则指的是 “对扩展开放&#xff0c;对修改关闭”。 当软件系统需要增加新的功能时&#xff0c;应该通过扩展现有代码的方式来实现&#xff0c;而不是去修改已有的代码。 例如我…...

【C语言系列】深入理解指针(3)

深入理解指针&#xff08;3&#xff09; 一、字符指针变量二、数组指针变量2.1数组指针变量是什么&#xff1f;2.2数组指针变量怎么初始化&#xff1f; 三、二维数组传参的本质四、函数指针变量4.1函数指针变量的创建4.2函数指针变量的使用4.3两段有趣的代码4.4 typedef关键字 …...

three.js+WebGL踩坑经验合集:写在前面的话

笔者从2023年初开始参与一个基于three.js引擎的web项目的开发工作。本打算2024年春节就把期间踩过的坑写到博客上分享给大家&#xff0c;然而哪怕本专栏的各种构思和内容已经在笔者的脑海里翻滚了一年&#xff0c;得了严重拖延症患者的我还是一直拖到了现在&#xff0c;实在惭愧…...

利用Linux的工作队列(Workqueue)实现中断下半部的处理

本文代码在哪个基础上修改而成&#xff1f; 本文是在博文 https://blog.csdn.net/wenhao_ir/article/details/145228617 的代码基础上修改而成。 关于工作队列(Workqueue)的概念 工作队列(Workqueue)可以用于实现Linux的中断下半部的&#xff0c;之前在博文 https://blog.cs…...

LabVIEW处理复杂系统和数据处理

LabVIEW 是一个图形化编程平台&#xff0c;广泛应用于自动化控制、数据采集、信号处理、仪器控制等复杂系统的开发。它的图形化界面使得开发人员能够直观地设计系统和算法&#xff0c;尤其适合处理需要实时数据分析、高精度控制和复杂硬件集成的应用场景。LabVIEW 提供丰富的库…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...