el-form nested el-table editing, verification information is displayed in the bubble box

overview

提示:这里可以添加技术概要
Under normal circumstances, el-table can edit the form. If the content of the input box is unreasonable, an error message will be displayed under the corresponding el-input.

However, I have to display the error message in the el-tooltip, because the verification failure message given by the product is really too long! ! !
Let’s not talk about other common sentences such as “required” and “please enter an integer”, let’s experience the prompt that the extra-long check of the form item fails:

由英文字母开头,只能包含英文字母、数字和下划线,最长32位,不能以下划线结尾

This sentence can be stretched in the form, but the leader requires that it is not allowed to open another pop-up box, and can only be edited in the form. The table column is only so wide, and there are so many items in the table. After being forced to insert it, the failed verification prompts in a row will start to fight:
①The error verification prompt is truncated and blocked by other columns .
②Forcibly adjusted .el-form-item__errorwidth, the error verification prompt The text at the bottom of the verification prompt is blocked by the next line tr
③Set the positioning, the control .el-form-item__erroris not blocked, and when the next item of the verification fails, this super long verification prompt is poked on the face of the next verification text
((ˉ▽ˉ ;)…)

overall architecture process

For the convenience of examples, only one form item description is placed here

Suppose you need to enter information for students, one of which is the student ID, and the naming rules for the ID are required: start with an English letter, only contain English letters, numbers, and underscores, up to 32 characters, and cannot end with an underscore
HTML part:

<template>
 <div>
 	<el-form :inline="true" :model="stuForm" ref="stuForm">
		<el-table :data="stuForm.stuData" @row-click="getRow" @current-change="clickCurrent" tooltip-effect="light">
			<el-table-column prop="code" label="标识:" align="center" :show-overflow-tooltip="true">
				<template v-slot="scope">
					<div class="edit-table">
						<!--编辑部分-->
						<el-form-item v-show="scope.row.isEdit" 
						:prop="'stuData.'+scope.$index+'.code'" 
						:rules="[{validator:(rule,value,callback)=>{checkCodeValue(rule,value,callback,scope.row)}}]">
							<el-tooltip 
							:disabled="scope.row.ms1&&scope.row.ms2"
							:content="scope.row.ms1?errorMess1:errorMess2"
							 placement="top" effect="light">
								<el-input v-model="scope.row.code" @blur="subRow(scope.$index,scope.row)"/>
							</el-tooltip>
						</el-form-item>
						<!--展示部分-->
						<el-tooltip :content="scope.row.code" placement="top" effect="light">
							<span v-show="!scope.row.isEdit" 
							 class="long-data-show">{
   
   {scope.row.code}}</span>
						</el-tooltip>
					</div>
				</template>
			</el-table-column>
		</el-table>
	</el-form>
 </div>
</template>

js processing:

<script>
export default {
      
      
	data(){
      
      
		return {
      
      
			errorMess1:"由英文字母开头,只能包含英文字母、数字和下划线,最长32位,不能以下划线结尾",
			errorMess2:"必填项不能为空",
			stuForm:{
      
      stuData:[]},//学生信息列表
		}
	},
	mounted(){
      
      this.loadData()},//初始化加载后台数据
	methods:{
      
      
		loadData(){
      
      
			//假设如下是获取学生信息的接口,加载后端分页第一页数据,每页10条
			//getStudentData({page:1,size:10}).then(res => {
      
      
				//初始化需要自己处理下数据,添三个属性
				let res = {
      
      data:[{
      
      code:'abc'},{
      
      code:'efg'}]}//模拟接口数据
				this.stuForm.stuData = [];
				//isEdit=是否显示输入框,ms1对应32位校验是否显示错误信息,ms2对应非空校验是否显示错误信息
				this.stuForm.stuData = res.data.map(item => {
      
      return {
      
      ...item,isEdit:false,ms1:true,ms2:true}})
			//})
		},
		checkCodeValue(rule,value,callback,row){
      
      //表单项单独校验处理
			let reg = /^[a-zA-Z]([a-zA-Z0-9_]{0,30}[a-zA-Z0-9])?$/;
			if(value === null || (value.toString().length === 0)){
      
      //非空校验
				row.ms1 = false;//非空不通,将另一32校验设为false,使disabled失效
				row.ms2= true;//非空不通,显示内容为非空校验错误提示,对应errorMess2
				callback(new Error(" "))//el-form自带提示处空白占位
			} else {
      
      //32位格式校验
				//同以上原理:都通,均设true使disabled触发;32校验不通,显示32校验的错误信息
				reg.test(value) ? (row.ms1 = true, row.ms2 = true, callback())
				:(row.ms1 = true, row.ms2 = false, callback(new Error(" ")));
			}
		},
		//其余辅助功能
		//点击表格其余行,关闭上次操作行的编辑框(可选择)
		clickCurrent(n,o){
      
      //对应newValue,oldValue,不明白可以去看下官网
			if(o)//o.isEdit = false;//直接关闭上一行编辑状态,或者:(看下一行)
			//下面这行看个人要求,如果想要校验规则不通过的行保持编辑状态,可额外加条件限制
			if(o.code.trim().length!==0)o.isEdit = false;
		},
		getRow(row){
      
      //点击表格行,点击的这行开启编辑输入框状态
			row.isEdit = true;
		},
		//某行失去焦点时提交这行内容给后台,前提是这行所有输入项校验通过
		validateRow(form,index){
      
      //目标行校验,这里单独拎出一个方法
			let result = true;
			for(let item of this.$refs[form].fields){
      
      //注意:如果是vue3,这里会报错,需要想别的办法
				if(item.prop.split(".")[1] == index){
      
      //注意:这里是”==“而不是”===“,如果项目采用严格模式,需要用number转换一下
					this.$refs[form].validateField(item.prop,err => {
      
      
						if(err.length)result = false;
					})
				}
				if(!result)break;
			}
			return result;
		},
		subRow(index,row){
      
      
			if(!this.validateRow("stuForm",index))return;//如果该行校验不通过,拒绝提交
			//subOne({code:row.code}).then(res => {//提交信息接口
				alert('提交成功') 
			//}).catch(er=>{row.isEdit = true})//如果接口反馈失败,保持输入状态方便识别刚刚编辑的行
			
		}
	}
}
</script>

Explanation of technical terms

Component built-in properties and methods used for list line processing:

1. @row-click: Click tr to trigger. It is used here to change the clicked line to edit state
2. @current-change: Triggered when the current line changes. This is used to (depending on the situation) close the editing state of the previous row
3. Use tooltip-effect="light"with : These two, when the content of the el-table cell is too long, the mouse moves in to display the super-long content in the form of a pop-up bubble 4. : Bubble style , there are two kinds of black and white 5, : Triggered when the input box loses focus. This is used to trigger the whole line check:show-overflow-tooltip="true"
effect="light"
@blur


technical details

About the method of verifying a single row:

validateRow(form,index){
    
    
	let result = true;
	for(let item of this.$refs[form].fields){
    
    
		if(item.prop.split(".")[1] == index){
    
    
			this.$refs[form].validateField(item.prop,err => {
    
    
				if(err.length)result = false;
			})
		}
		if(!result)break;
	 }
	return result;
},

1. item.propThe format of the obtained data:
first line: stuData.0.code
second line: stuData.1.code
third line: stuData.2.code
...
In short, the middle index corresponds to the row index of the data in the list, prop="'stuData.'+scope.$index+'.code'"Specifically according to the binding in the form:

2. Note: In the case of vue3+element-plus, this.$refs[form].fieldsthe error undefined will be reported. After printing and monitoring, it is found that the printing results of the high version and the low version this.$refs.formare different, and there is no solution for the time being. The difference is as follows:
insert image description here

Guess you like

Origin blog.csdn.net/weixin_43939111/article/details/130961822