el-element——el-table嵌入el-input el-table表格内容编辑 el-table编辑 el-table嵌套input 实现表单

需求描述:table中有多个需要编辑的字段,并且需要校验空值或非正数

在这里插入图片描述

1.方案

一. 手搓el-input + div

仿照el-form校验提示,用el-input和div写样式,满足需求。

问题:列表数据量大,不好控制提示显示隐藏。保存时校验值需要遍历列表挨个字段判空

二. el-form + el-input

把form和input封装到一个组件中,列表上每一个input,其实是form + input

2.组件代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

// 子组件核心
validChange(val) {
    let isValid = null; // 父级使用判断该form是否通过表单校验
    this.isFocus = false
    // 个人业务需求 start (可删除)
    // 保留两位小数显示
    if (parseFloat(val).toString() !== 'NaN') {
        this.value = parseFloat(val).toFixed(2)
    }
    // 个人业务需求 end
    // 给form赋值
    this.form[this.propValue] = this.value;
    this.$refs["formRef"].validate(valid => {
        if (valid) {
            isValid = true
            this.$emit("updateData", this.value);
        } else {
            isValid = false
        }
    });
    return isValid
}

3. 父组件调用

// 自己和子组件对应一下传参
<el-table-column label="采购单价" align="left" width="120" prop="bugSinPrice">
   <template slot-scope="scope">
       <valid-input
           :ref="`bugSinPriceRef${scope.$index}`"
           :labelValue="'采购单价'"
           propValue="bugSinPrice"
           :indexValue="scope.$index"
           :unit="'元'"
           @updateData="val => scope.row.bugSinPrice = val"
       />
   </template>
 </el-table-column>
 // 提交信息
 handleSubmit() {
     let refList = this.$refs
     Object.keys(refList).forEach(key => {
         if (this.$refs[[key]] && this.$refs[[key]].validChange) {
             // 如果 this.$refs[[key]].validChange() 有一个为false
             // 说明有数据没填禁止提交
             // 后续逻辑...
         }
     })
 }

4.通用性处理(续)

第一版:只处理了input组件并且没有回显初始化的数据
第二版:新增了el-date-picker 和 el-select组件
组件变动
	/**
	*这部分是props的修改
	*传参增加了 initValue 渲染的初始值
	*传参增加了 select* 相关参数
	*/
	// 默认值
	initValue: {
	    type: String,
	    default: () => {
	        return ''
	    }
	},
	// 选择框传参 start
	selectOptions: {
	    type: Array,
	    default: () => {
	        return []
	    }
	},
	selectLabel: {
	    type: String,
	    default: () => {
	        return 'value'
	    }
	},
	selectKey: {
	    type: String,
	    default: () => {
	        return 'value'
	    }
	}
	// 选择框传参 end
	/**
	*form表单校验修改
	*根据需要显示的组件自定义校验规则
	*因为是通用型组件,校验规则没有涉及太多业务需求
	*/
	let formCheck = (rule, value, callback) => {
	    switch (this.itemType) {
	        // 输入框组件校验
	        case 'input':
	            const reg1 = /^(-)?[0-9]+([.][0-9]{1,})?$/
	            const reg2 = /^-[0-9]+([.][0-9]{1,})?$/
	            if (!value) {
	                callback(new Error(`${this.labelValue}不能为空`))
	            } else {
	                // 判断是否为数字
	                if (reg1.test(value)) {
	                    // 判断是否为正数
	                    if (reg2.test(value)) {
	                        callback(new Error('不能输入负数'))
	                    } else {
	                        callback()
	                    }
	                } else {
	                    callback(new Error('只能输入数字'))
	                }
	            }
	            break;
	        // 选择框组件校验
	        case 'select':
	            if (!value) {
	                callback(new Error(`${this.labelValue}不能为空`))
	            } else {
	                callback()
	            }
	            break;
	        // 日期组件校验
	        case 'date':
	            if (!value) {
	                callback(new Error(`${this.labelValue}不能为空`))
	            } else {
	                callback()
	            }
	    }
	}
	created() {
	    // $set设置值,保证参数为响应式
	    this.$set(this.form, this.propValue, this.initValue);
	    // 新增:设置传入的值当做默认值
	    this.value = this.initValue
	},
	// 失去焦点更新
	validChange(val) {
	    this.isFocus = false
	    let isValid = null; // 父级使用判断该form是否通过表单校验
	    // 修改 start
	    // 根据显示组件类型,在数据更新时做数据处理(根据自己的业务需求来)
	    if (this.itemType === 'input') {
	        // 保留两位小数显示
	        if (parseFloat(val).toString() !== 'NaN') {
	            this.value = parseFloat(val).toFixed(2)
	        }
	    }
	    // 修改 end
	    // 给form赋值
	    this.form[this.propValue] = this.value;
	    this.$refs["formRef"].validate(valid => {
	        if (valid) {
	            isValid = true
	            this.$emit("updateData", this.value);
	        } else {
	            isValid = false
	        }
	    });
	    return isValid
	}
调用变动
/**
* 新增
* itemType 显示的组件类型
* init-value 渲染的默认值
* select组件需要额外传参
* 1.select-options select列表数据
* 2.select-key 根据列表数据自定义 key 字段名
* 3.select-label 根据列表数据自定义 label 字段名
*/
<template slot-scope="scope">
    <table-item-valid
        :ref="`preDate${scope.$index}`"
        itemType="date"
        :labelValue="'预计交货日期'"
        propValue="preDate"
        :indexValue="scope.$index"
        :init-value="scope.row.preDate"
        @updateData="val => scope.row.preDate = val"
    />
</template>

Tip:后续会使用类似插槽实现自定义组件嵌套校验

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值