需求描述:
在el-table中,对每一行数据的数量进行校验,对于数量要用el-input输入框进行输入数值。
校验主要涉及:每次输入的时候都要清空el-input输入框的数值,输入值只能为数字,并且要对输入的数量进行判断是否超过库存的最大数量。
问题描述:
因为实在el-tablel里面嵌套输入框,所以不可避免需要借助于scope卡槽来完成需求。但是,因为输入框是通过scope.row.number进行绑定的,所以在这里如何如果不满足条件,如何对卡槽数据进行相对应的修改,成了一个比较大的问题。
解决思路:
(1)在数据校验的时候,主要借助于oninput、onkeyup、onfocus。
(2)在对scope.row绑定的数据进行相对应的修改的时候,主要借助于this.$set()。
(3)再触发事件的时候主要借助于@click.native、v-on:mouseover.native、v-on:mouseleave.native
在这里我主要贴校验的实验代码:
(1)前端:
<el-table-column label="数量" align="center" width="120" prop="aldQty">
<template slot-scope="scope">
<template v-if="scope.row.editaldQty">
<el-input
oninput ="value=value.replace(/[^0-9.]/g,'0')"
onkeyup="this.value=this.value.match(/\d+\.?\d{0,2}/);this.dispatchEvent(new Event('input'))"
onfocus=" this.value = ''"
v-model="scope.row.aldQty" ref="inputaldQty" @click.native = "mouseLeavealdQty(scope.row.aldQty,scope.$index,scope)" v-on:mouseover.native="mouseOveraldQty" v-on:mouseleave.native="mouseLeavealdQty(scope.row.aldQty,scope.$index,scope)"></el-input>
</template>
<span v-if="!scope.row.editaldQty && scope.row.aldQty>0 && scope.row.aldQty < fromData.salesOrderDetailToList[scope.$index]['invStockQty']">
{{format(scope.row.aldQty)}}
</span>
</template>
</el-table-column>
(2)方法:
mouseLeavealdQty(number,index,scope) {
console.log("获取到的"+scope)
console.log("获得此物料的库存数量"+this.fromData.salesOrderDetailToList[index]['invStockQty']);
const upNumber = this.fromData.salesOrderDetailToList[index]['invStockQty'];
console.log("获得悬浮的数值"+number)
console.log("获得的索引为"+index)
if(number > upNumber){
this.$modal.msgError("所选中的物料转出的数量大于库存数量")
//对所选scope绑定的数据进行修改
this.$set(this.fromData.salesOrderDetailToList[index],'aldQty',1);
}
this.$refs.inputaldQty.blur();
},
mouseOveraldQty() {
this.$refs.inputaldQty.focus();
},
(1)oninput
功能描述:事件在用户输入时触发。
oninput ="value=value.replace(/[^0-9.]/g,'0')"
这句代码的意思就是借助于正则表达式将对于每个输入值如果不是数字则将其替换为数字。
(2)onkeyup
功能描述:事件会在键盘按键被松开时发生。
onkeyup="this.value=this.value.match(/\d+\.?\d{0,2}/);this.dispatchEvent(new Event('input'))"
但是这里有个坑:
vue的v-model是监听input框的input事件生效的。而通过value直接操作dom元素,vue的v-model是监听不到的!所以要手动分发一个input事件使v-model监听。this.dispatchEvent(new Event(‘input’))。当然这样会导致这句代码在每个input里面复用。也搜过其他人的封装。都感觉不是很灵活,只针对一种正则进行限制。留个坑看以后会不会封装吧。
(3)onfocus
功能描述:事件在对象获得焦点时发生。
onfocus=" this.value = ''"
这句代码解决了每次点击的时候,输入框都会被清空。
(4)@click.native
作用描述:给组件绑定原生事件。
@click.native = "mouseLeavealdQty(scope.row.aldQty,scope.$index,scope)"
在这里如果给el-input组件绑定@click时间是不会被触发的。所以要加@click.native 。
补充:当父组件中引入子组件的时候,当要触发子组件点击事件的时候@click 不生效。
(5)v-on:mouseover.native、 v-on:mouseleave.native
这个其实类似于上面讲的,一个是鼠标移入到输入框则触发该事件,另一个则是鼠标移除的时候触发改事件。
(6)如何解决改变scope.row.属性值 所绑定的数值
在这里我们可以看出v-model=“scope.row.aldQty”,我们通过this.$set()方法来进行改变。
//对所选scope绑定的数据进行修改
this.$set(this.fromData.salesOrderDetailToList[index],'aldQty',1);
对于this.$set()如何使用大家可以参考我之前的两篇文章。
(a)vue中this.$set()的用法
https://blog.csdn.net/weixin_43388691/article/details/127423040?spm=1001.2014.3001.5502
(b)el-table+el-tree+el-select动态选择对应值
https://blog.csdn.net/weixin_43388691/article/details/127385435?spm=1001.2014.3001.5502