【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 :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技术快速部署虚拟机
前言:这个系列将使用最前沿的cursor作为辅助编程工具,来快速开发一些基础的编程项目。目的是为了在真实项目中,帮助初级程序员快速进阶,以最快的速度,效率,快速进阶到中高阶程序员。 本项目将基于谷粒商城…...
26、正则表达式
目录 一. 匹配字符 .:匹配除换行符外的任意单个字符。 二. 位置锚点 ^:匹配输入字符串的开始位置。 $:匹配输入字符串的结束位置。 \b:匹配单词边界。 \B:匹配非单词边界。 三. 重复限定符 *:匹配…...
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 语言中,动态内存分配主要是通过 malloc() 和 free() 函数来完成的。而在 C 中是使用new和delete关键字,来动态分配内存。 虽然 C 语言没有 new,但 malloc() 和 new 在内存分配上的作用是相似的。下面我们详细解释 malloc() 和 ne…...
QT:控件属性及常用控件(3)-----输入类控件(正则表达式)
输入类控件既可以进行显示,也能让用户输入一些内容! 文章目录 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值的比对过程,期间遇到2个问题,解决起来花费了一点时间 1. png 和 plist 生成zip的时候再生成MD5值会发生变动。 这个问题解决起来有2种方案: (1).第一个方案是将 png和plist的文件时间改…...
博客搭建 — GitHub Pages 部署
关于 GitHub Pages GitHub Pages 是一项静态站点托管服务,它直接从 GitHub 上的仓库获取 HTML、CSS 和 JavaScript 文件,通过构建过程运行文件,然后发布网站。 本文最终效果是搭建出一个域名为 https://<user>.github.io 的网站 创建…...
翻译:How do I reset my FPGA?
文章目录 背景翻译: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 背景 在写博客《复位信号的同步与释放(同步复…...
Linux 进程环境变量:深入理解与实践指南
🌟 快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。🌟 🚩用通俗易懂且不失专业性的文字,讲解计算机领域那些看似枯燥的知识点🚩 在 Linux 系统里…...
Linux探秘坊-------5.git
1.git介绍 1.版本控制器 为了能够更⽅便我们管理这些不同版本的⽂件,便有了版本控制器。所谓的版本控制器,就是能让你了解到⼀个⽂件的历史,以及它的发展过程的系统。通俗的讲就是⼀个可以记录⼯程的每⼀次改动和版本迭代的⼀个管理系统&am…...
Linux中的几个基本指令(二)
文章目录 1、cp指令例一:例二:例三:例四:例五: 2、mv 指令例一:例二: 3、cat指令例一: 4、tac指令5、which指令6、date指令时间戳:7、zip指令 今天我们继续学习Linux下的…...
Java入门笔记(1)
引言 在计算机编程的广袤宇宙中,Java无疑是一颗格外耀眼的恒星。那么,Java究竟是什么呢? Java是美国Sun公司(Stanford University Network)在1995年推出的一门计算机高级编程语言。曾经辉煌的Sun公司在2009年被Oracle&…...
设计模式的艺术-开闭原则
原则使用频率图(仅供参考) 1.如何理解开闭原则 简单来说,开闭原则指的是 “对扩展开放,对修改关闭”。 当软件系统需要增加新的功能时,应该通过扩展现有代码的方式来实现,而不是去修改已有的代码。 例如我…...
【C语言系列】深入理解指针(3)
深入理解指针(3) 一、字符指针变量二、数组指针变量2.1数组指针变量是什么?2.2数组指针变量怎么初始化? 三、二维数组传参的本质四、函数指针变量4.1函数指针变量的创建4.2函数指针变量的使用4.3两段有趣的代码4.4 typedef关键字 …...
three.js+WebGL踩坑经验合集:写在前面的话
笔者从2023年初开始参与一个基于three.js引擎的web项目的开发工作。本打算2024年春节就把期间踩过的坑写到博客上分享给大家,然而哪怕本专栏的各种构思和内容已经在笔者的脑海里翻滚了一年,得了严重拖延症患者的我还是一直拖到了现在,实在惭愧…...
利用Linux的工作队列(Workqueue)实现中断下半部的处理
本文代码在哪个基础上修改而成? 本文是在博文 https://blog.csdn.net/wenhao_ir/article/details/145228617 的代码基础上修改而成。 关于工作队列(Workqueue)的概念 工作队列(Workqueue)可以用于实现Linux的中断下半部的,之前在博文 https://blog.cs…...
LabVIEW处理复杂系统和数据处理
LabVIEW 是一个图形化编程平台,广泛应用于自动化控制、数据采集、信号处理、仪器控制等复杂系统的开发。它的图形化界面使得开发人员能够直观地设计系统和算法,尤其适合处理需要实时数据分析、高精度控制和复杂硬件集成的应用场景。LabVIEW 提供丰富的库…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
