基于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定制化开发中,在做系统定制化开发中,在对系统的静态壁纸做定制的时候,需要增加几种静态壁纸可以让用户自己设置壁纸,所以可以在壁纸的系统应用中 添加几种静态壁纸图片,然后配置好 就可以在选择壁纸的时候,作为静态壁纸,接下来看如何具体实现这个…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制
在数字化浪潮席卷全球的今天,数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具,在大规模数据获取中发挥着关键作用。然而,传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时,常出现数据质…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
