基于element-plus定义表格行内编辑配置化
文章目录
- 前言
- 一、新增table组件
- 二、使用步骤
前言
在 基于element-plus定义表单配置化 基础上,封装个Element-plus的table表格
由于表格不同于form组件,需自定义校验器,以下组件配置了单个校验,及提交统一校验方法,且自定义必填校验*显示和校验错误部分边框标红等,实际可根据业务及不同场景优化改造相关定义
后期抽空新增表格行及删除行等功能,

一、新增table组件
- table-configuration/index.vue
<template><el-tableborderref="tableRef":show-header="showHeader":data="tableData"style="width: 100%"tooltip-effect:max-height="tablemaxHeight"><el-table-column type="selection" :fixed="selectionFixed" width="55" v-if="hasSelection"/><template v-for="(item, index) in tableProperty" :key="item"><el-table-column:align="align":sortable="item.sortable":min-width="item.width":show-overflow-tooltip="showOverflowTooltip":label="item.label"><template #header><div :class="[getTableHeader(item.property.rules)]" v-html="item.label"></div></template><template #default="scope"><component :class="[scope.$index >=0 && getIsErrorClass(scope.$index, index)]"v-model:content="scope.row[item.field]"v-model="scope.row[item.field]":property="{...item.property, name: item.field}":is="item.type"@fieldBlur="(val) => blur(val, item, scope.$index, index)"@fieldChange="(val) => change(val, item, scope.$index, index)" /></template></el-table-column></template></el-table>
</template>
<script lang="ts" src="./index.ts"/>
<style lang="less">
.is-error .el-select-v2__wrapper,.is-error .el-select-v2__wrapper:focus,.is-error .el-textarea__inner,.is-error .el-textarea__inner:focus {box-shadow: 0 0 0 1px var(--el-color-danger) inset
}.is-error .el-input__wrapper {box-shadow: 0 0 0 1px var(--el-color-danger) inset
}
.table {&_header:before {content: "*";color: var(--el-color-danger);margin-right: 4px;}
}
</style>
- table-configuration/index.ts
import { tableHooks } from "@/composables/table-hooks";
import { computed, defineComponent, reactive, ref } from "vue";
import Input from "@/components/form-configuration/input.vue";
import Select from "@/components/form-configuration/select.vue";
import Vhtml from "@/components/form-configuration/v-html.vue";
import Upload from "@/components/form-configuration/upload.vue";
import Switch from "@/components/form-configuration/switch.vue";
import Radio from "@/components/form-configuration/radio.vue";
import Checkbox from "@/components/form-configuration/checkbox.vue";
import Date from "@/components/form-configuration/date.vue";
import Cascader from "@/components/form-configuration/cascader.vue";
import { isArray } from "lodash-es";
import { ElMessage } from "element-plus";
import type { rulesType } from "@/interface";const ruleType = {required: false,message: '',trigger: '',validator: (val: any) =>{return val}
}
const fieldProperty = {label: 'demo',type: 'Input',field: 'demo',width: '120px',err: '',property: {maxlength: 200,rules: [ruleType]}
}
export default defineComponent({components: {Input,Select,Vhtml,Upload,Switch,Radio,Checkbox,Date,Cascader,},props: {align: {type: String,default: 'left', // left / center / right},showHeader: {type: Boolean,default: true,},selectionFixed: {type: Boolean,default: false,},showOverflowTooltip: {type: Boolean,default: true,},hasSelection: {type: Boolean,default: false,},property: {type: Object,default() {return [ fieldProperty ];},},data: {type: Object,default() {return {};},},},setup(props, { emit }) {const { tablemaxHeight } = tableHooks();const tableRef = ref()const tableData = computed({get() {return props.data;},set(val) {emit("update:data", val);},});const noType = 'noType'const tableProperty = computed(() => props.property);const blur = (val: any, item: typeof fieldProperty, rowIndex: number, colIndex: number) => {let arr: Array<boolean> = []if (item.property.rules && isArray(item.property.rules)) {arr = validateForField(item, val, 'blur', rowIndex, colIndex)}if (!arr.length) {emit('blur', {val, field: item.field, rowIndex, colIndex}) // 触发clearIsError(rowIndex, colIndex)}}const change = (val: any, item: typeof fieldProperty, rowIndex: number, colIndex: number) => {let arr: Array<boolean> = []if (item.property.rules && isArray(item.property.rules)) {arr = validateForField(item, val, 'change', rowIndex, colIndex)}if (!arr.length) {emit('change', {val, field: item.field, rowIndex, colIndex}) // 触发clearIsError(rowIndex, colIndex)}}const isError = ref<{rowIndex: number, colIndex: number}[]>([])const validateForField = (item: typeof fieldProperty, val: any, type: string, rowIndex: number, colIndex: number) => {let arr: Array<boolean> = []item.property.rules.forEach((valid) => {const types = [valid.trigger, noType]if (valid.required && !val) {ElMessage.error(valid.message)arr.push(false)isError.value.push({rowIndex, colIndex,})return}if (!valid.required && !val || !types.includes(type)) returnif (!valid.validator) returnconst bool = valid.validator(val)if (!bool) {ElMessage.error(valid.message)arr.push(bool)isError.value.push({rowIndex, colIndex,})}})return arr}const clearIsError = (rowIndex: number, colIndex: number) => {if (rowIndex === -1) {isError.value = []} else {isError.value = isError.value.filter((item) => {return !((item.rowIndex === rowIndex) && (item.colIndex === colIndex))})}}const validate = () => {let arr: Array<boolean> = []clearIsError(-1, -1)tableData.value.forEach((data: object, rowIndex: number) => {tableProperty.value.forEach((tabPro: any, colIndex: number) => {if (!tabPro.property.rules) returnconst field = tabPro.field as keyof typeof dataarr.push(...validateForField(tabPro, data[field], noType, rowIndex, colIndex))});});return !arr.length}const getIsErrorClass = computed(() => {return (rowIndex: number, colIndex: number) => {let bool = falseisError.value.forEach((error) => {(error.rowIndex === rowIndex) && (error.colIndex === colIndex) && (bool = true)})return bool ? 'is-error' : ''}})const getTableHeader = (rules: rulesType[]) => {if (!rules) return ''return !!rules.filter((item) => item.required).length ? 'table_header' : ''}return {tableRef,tablemaxHeight,tableProperty,tableData,isError,getIsErrorClass,getTableHeader,change,blur,validate};},
});
二、使用步骤
<TableConfigurationref="supplierListRef"v-model:data="supplierListEntity.product":hasSelection="true":selectionFixed="true":property="tableProperty"align="center"/>
import { defineComponent, reactive, ref } from 'vue'
import TableConfiguration from '@/components/table-configuration/index.vue'
export default defineComponent({components: {TableConfiguration},setup() {const tableRef = ref()const tableProperty = reactive([{ label: 'Input01', type: 'Input', field: 'Input01', property: {maxlength: 500,rules: [{ required: false, message: 'error', trigger: 'blur', validator: (value: string) => {return /^\+?[1-9][0-9]*$/.test(value)}}]}},{ label: 'Input02', type: 'Input', field: 'Input02', width: '200px', property: {maxlength: 500,rules: [{ required: true, message: 'error', trigger: 'blur' }]}}])const tableEntity = reactive({table: [{Input01: '',Input02: '',}]})const validate = () => {tableRef.value.validate()}return {tableRef,tableProperty,tableEntity,validate}},
})
相关文章:
基于element-plus定义表格行内编辑配置化
文章目录 前言一、新增table组件二、使用步骤 前言 在 基于element-plus定义表单配置化 基础上,封装个Element-plus的table表格 由于表格不同于form组件,需自定义校验器,以下组件配置了单个校验,及提交统一校验方法,且…...
WebGL-Vue3-TS-Threejs:基础练习 / Javascript 3D library / demo
一、理解Three.js Three.js是一个用于WebGL渲染的JavaScript库。它提供了一组工具和类,用于创建和渲染3D图形和动画。简单理解(并不十分准确),Three.js之于WebGL,好比,jQuery.js之于JavaScript。 OpenGL …...
2022年12月 Python(四级)真题解析#中国电子学会#全国青少年软件编程等级考试
Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 有n个按名称排序的商品,使用对分查找法搜索任何一商品,最多查找次数为5次,则n的值可能为?()(2分) A.5 B.15 C.30 D.35 答案:C 答案解析:对分查找最多查找次数m与个数之间n的…...
确定性 vs 非确定性:GPT 时代的新编程范式
分享嘉宾 | 王咏刚 责编 | 梦依丹 出品 | 《新程序员》编辑部 在 ChatGPT 所引爆的新一轮编程革命中,自然语言取代编程语言,在只需编写提示词/拍照就能出程序的时代,未来程序员真的会被简化为提示词的编写员吗?通过提示词操纵 …...
【Linux奇遇记】我和Linux的初次相遇
🌈个人主页: Aileen_0v0 🔥系列专栏:Linux奇遇记系列专栏💫"没有罗马,那就自己创造罗马~" 目录 前端和后端的介绍 1.前端 2.后端 3.前后端区别 Linux在前后端开发中的角色 如何学习Linux 去进行程序开发 Linux的常见根目…...
剪贴板劫持--PasteJacker的使用
启动 PasteJacker [1] Windows [2] Linux [3] Exit第一次是让我们选择要攻击针对的目标系统,这里以Windows系统为例,即我自己的物理机 因此键入 1 ,回车 [1] Download and execute a msfvenom backdoor using certutil (Web delivery Past…...
说一下vue2的响应式原理?
vue2采用数据代理数据劫持发布订阅模式的方法。 在初始化vue实例时,会把data对象和data对象的属性都添加到vm对象中,通过object.defineProperty()进行数据代理,用vm对象的属性来代理data对象的属性,并在Observer类中递归遍历data…...
如何使用CORS和CSP保护前端应用程序安全
前端应用在提供无缝用户体验方面起着核心作用。在当今互联网的环境中,第三方集成和API的普及使得确保强大的安全性至关重要。安全漏洞可能导致数据盗窃、未经授权访问以及品牌声誉受损。本文将向您展示如何使用CORS和CSP为您的网页增加安全性。 嗨,大家好…...
C/C++输出硬币翻转 2021年6月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
目录 C/C硬币翻转 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C硬币翻转 2021年6月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 假设有N个硬币(N为不大于5000的正整数),从1…...
ipad可能会在iOS 16中失去智能家居中心功能
在iOS 16测试版代码中发现的文本表明苹果将放弃对iPad家庭中心的支持 家庭app迎来重大改版,未来更将对智能家居互联互通标准Matter提供支持。 即使某一款智能家居设备再优秀,只要它没有接入HomeKit,那么就不能在苹果的家庭app中直接管理控制。…...
maven打包可运行jar
普通java程序 <build><finalName>JavaDeviceClient</finalName><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version>2.3.2</version><configuration><source>1.8</source><…...
Arcgis连接Postgis数据库(Postgre入门十)
效果 步骤 1、矢量数据首先有在postgis数据库中 这个postgis数据库中的一个空间数据,数据库名称是test3,数据表名称是test 2、Arcgis中连接postgis数据库中 3、成功连接 可以将数据拷贝或导入到gdb数据库中...
【蓝桥杯选拔赛真题17】C++时间换算 第十二届蓝桥杯青少年创意编程大赛C++编程选拔赛真题解析
目录 C/C++时间换算 一、题目要求 1、编程实现 2、输入输出 二、算法分析 <...
【腾讯云 HAI域探秘】探索AI绘画之路:利用腾讯云HAI服务打造智能画家
目录 前言1 使用HAI服务作画的步骤1.1 注册腾讯云账户1.2 创建算力服务器1.3 进入模型管理界面1.4 汉化界面1.5 探索AI绘画 2 模型参数的含义和调整建议2.1 模型参数的含义和示例2.2 模型参数的调整建议 3 调整参数作画的实践和效果3.1 实践说明3.2 实践效果13.3 实践效果23.4 …...
安卓常见设计模式10------责任链模式(Kotlin版)
1. W1 是什么,什么是责任链模式? 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它用于将请求的发送者和接收者解耦,并将请求沿着一个处理链进行传递,直到有一个处理者能…...
利用 Google Artifact Repository 构建maven jar 存储仓库
参考了google 官方文档 https://cloud.google.com/artifact-registry/docs/java/store-java#gcloud_1 首先 enable GAR api gcloud services enable artifactregistry.googleapis.com gcloud services list | grep -i artifact artifactregistry.googleapis.com Artifac…...
Facebook广告被暂停是什么原因?Facebook广告账号被封怎么办?
许多做海外广告投放的小伙伴经常遇到一个难题,那就是投放的Facebook广告被拒或 Facebook 广告帐户被关闭赞停的经历,随之而来的更可能是广告账户被封,导致资金的损失。本文将从我自身经验,为大家分享,Facebook广告被暂…...
Javaweb之javascript的BOM对象的详细解析
1.5.2 BOM对象 接下来我们学习BOM对象,BOM的全称是Browser Object Model,翻译过来是浏览器对象模型。也就是JavaScript将浏览器的各个组成部分封装成了对象。我们要操作浏览器的部分功能,可以通过操作BOM对象的相关属性或者函数来完成。例如:…...
使用Nginx和Spring Gateway为SkyWalking的增加登录认证功能
文章目录 1、使用Nginx增加认证。2、使用Spring Gateway增加认证 SkyWalking的可视化后台是没有用户认证功能的,默认下所有知道地址的用户都能访问,官网是建议通过网关增加认证。 本文介绍通过Nginx和Spring Gateway两种方式 1、使用Nginx增加认证。 生…...
Android 12.0 增加多张图片作为系统静态壁纸的功能实现
1.前言 在12.0的系统rom定制化开发中,在做系统定制化开发中,在对系统的静态壁纸做定制的时候,需要增加几种静态壁纸可以让用户自己设置壁纸,所以可以在壁纸的系统应用中 添加几种静态壁纸图片,然后配置好 就可以在选择壁纸的时候,作为静态壁纸,接下来看如何具体实现这个…...
[特殊字符] Meixiong Niannian画图引擎效果实测:1024×1024输出在印刷级DPI下的表现
Meixiong Niannian画图引擎效果实测:10241024输出在印刷级DPI下的表现 1. 项目概述 Meixiong Niannian画图引擎是一款专为个人GPU设计的轻量化文本生成图像系统。该系统基于Z-Image-Turbo底座,深度融合了Niannian专属Turbo LoRA微调权重,针…...
EmojiOne Color彩色字体:3分钟掌握1800+表情的终极解决方案
EmojiOne Color彩色字体:3分钟掌握1800表情的终极解决方案 【免费下载链接】emojione-color OpenType-SVG font of EmojiOne 2.3 项目地址: https://gitcode.com/gh_mirrors/em/emojione-color 想要在网站、应用或设计作品中添加生动有趣的彩色表情符号吗&am…...
7款加密压缩包密码测试工具:ArchivePasswordTestTool技术深度解析
7款加密压缩包密码测试工具:ArchivePasswordTestTool技术深度解析 【免费下载链接】ArchivePasswordTestTool 利用7zip测试压缩包的功能 对加密压缩包进行自动化测试密码 项目地址: https://gitcode.com/gh_mirrors/ar/ArchivePasswordTestTool 在数字资产管…...
长沙金海中学答题:中天电子实现精准调控
课堂困境与答题需求长沙金海中学在传统教学模式中,面临着诸多答题相关的痛点。每次进行50题的答题测试,教师需要花费30分钟以上的时间进行人工批改,这不仅耗时耗力,还容易出现批改错误。同时,课堂互动参与率不足30%&am…...
博士论文不是“本科生Pro版”,好写作AI的“学术脚手架”让孤独的长征有迹可循
在多年的论文写作科普中,我最常被博士生问到的问题不是“怎么写”,而是“凭什么”。 凭什么我的研究是“原创”?凭什么我的论证经得起拷问?凭什么我的理论贡献能让答辩委员会点头? 这些问题的背后,藏着一…...
Excel太宽导出PDF乱码?4个简单技巧帮你把Excel表格转成PDF
在日常办公中,我们经常会遇到Excel表格内容过宽的问题,比如数据列太多、表格横向延伸过长,导致打印或分享时排版混乱。这时候将Excel转为PDF格式就成了关键——PDF格式能完美保留表格的原始排版,避免内容错位,还能方便…...
AI智能改写技术加持,aibiye等9款查重工具免费不限次数,助力论文质量飞跃
核心工具对比速览 工具名称 查重速度 降重效果 特色功能 适用场景 aicheck 极快 重复率可降30% 专业术语保留 高重复率紧急处理 aibiye 中等 逻辑优化明显 学术表达增强 提升论文质量 askpaper 快 结构保持完整 多语言支持 外文论文降重 秒篇 极快 上下文…...
从Qt 5.7到C++17:一文搞懂qAsConst的来龙去脉与实战应用
从Qt 5.7到C17:深入解析qAsConst的设计哲学与工程实践 在Qt框架的演进历程中,qAsConst函数的引入标志着Qt与C标准的一次重要融合。这个看似简单的工具函数背后,蕴含着Qt容器设计哲学与C现代语法特性的精妙平衡。本文将带您穿越技术迷雾&#…...
企业知识库升级:Qwen3-Reranker-0.6B重排序实战案例
企业知识库升级:Qwen3-Reranker-0.6B重排序实战案例 1. 引言:企业知识检索的痛点与解决方案 在当今信息爆炸的时代,企业知识库已成为组织内部信息流转的核心枢纽。然而,传统的关键词匹配和简单向量检索往往难以准确理解用户查询…...
打造个人专属数字图书馆:Talebook私有书库的三大核心优势
打造个人专属数字图书馆:Talebook私有书库的三大核心优势 【免费下载链接】talebook 一个简单好用的个人书库 项目地址: https://gitcode.com/gh_mirrors/ta/talebook 你是否曾梦想拥有一个完全由自己掌控的数字图书馆?一个可以随时随地访问、管理…...
