填写数字 保留2位小时 并自动补0参考文章:
https://blog.csdn.net/m0_37843876/article/details/107084740
需要实现的效果:
blur 失焦后
1 ==> 1.00
1.2 ==> 1.20
1.333 ==> 1.33
最开始的样子
<el-col :span="8">
<el-form-item label="金额" prop="account.amount" class="formItem" :rules="filter_rules({required:true, type: 'mustTwoFigures', maxLength:21})">
<el-input v-model="list.account.amount" clearable style="width: 100%;"></el-input>
</el-form-item>
</el-col>
代码修改第一版
<el-col :span="8">
<el-form-item label="金额" prop="account.amount" class="formItem" :rules="filter_rules({required:true, maxLength:21})">
<el-input v-model="list.account.amount" clearable style="width: 100%;" oninput="value=value.replace(/[^0-9.]/g,'')" @blur="utils.blur($event)"></el-input>
</el-form-item>
</el-col>
blur: function (e) {
if (e.target.value.indexOf(".") != -1) {
let str = e.target.value.split(".");
if (str[0].length > 0) {
let arr = str[0].split("");
let res = arr.every((item, index) => {
return item == 0 || item == "0";
});
if (res) {
if (str[1]) {
e.target.value = "0." + str[1];
} else {
e.target.value = "0.00";
}
} else {
if (str[1]) {
e.target.value = str[0].replace(/\b(0+)/g, "") + "." + str[1];
} else {
e.target.value = str[0].replace(/\b(0+)/g, "") + ".00";
}
}
}
if (str[1].length == 1) {
e.target.value = e.target.value + "0";
}
if (str[1].length > 2) {
e.target.value = e.target.value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3');//只能输入两个小数
}
} else {
let arr = e.target.value.split("");
let res = arr.every((item, index) => {
return item == 0 || item == "0";
});
if (res) {
// e.target.value = "0.00";
} else {
e.target.value = e.target.value.replace(/\b(0+)/g, "") + ".00";
}
}
}
blur被我抽出放utils里了 全局方法 可以少复制几份
当时我大概测了一下 觉得没啥大问题 美滋滋填数据的时候 发现保存时 会发生明明填写了 保存时form会报未填校验
这个表单字段有300来个 我挨个填完告诉我校验过不去 诶嘛 大型崩溃现场
而且我发现 页面上虽然自动补0显示是没啥问题 例如22.00 但是给后台带的对象里值仍然是22!!!
错误原因:网上查的文章说 vue的v-model是监听input框的input事件生效的
我事件对象e.target.value补0是直接操作dom元素 vue的v-model监听不到
解决办法:
e.target.value赋值后 需要手动触发input事件 v-model才能同步更新
dispatchEvent(new Event(‘input’))
最后一版代码
<el-col :span="8">
<el-form-item label="金额" prop="ccount.amount" class="formItem" :rules="filter_rules({required:true, type: 'mustTwoFigures', maxLength:21})">
<el-input v-model="list.account.amount" clearable style="width: 100%;" @blur="utils.blur($event)"></el-input>
</el-form-item>
</el-col>
blur: function (e) {
if (e.target.value.indexOf(".") != -1) {
let str = e.target.value.split(".");
if (str[0].length > 0) {
let arr = str[0].split("");
let res = arr.every((item, index) => {
return item == 0 || item == "0";
});
if (res) {
if (str[1]) {
e.target.value = "0." + str[1];
e.target.dispatchEvent(new Event('input'))
} else {
e.target.value = "0.00";
e.target.dispatchEvent(new Event('input'))
}
} else {
if (str[1]) {
e.target.value = str[0].replace(/\b(0+)/g, "") + "." + str[1];
e.target.dispatchEvent(new Event('input'))
} else {
e.target.value = str[0].replace(/\b(0+)/g, "") + ".00";
e.target.dispatchEvent(new Event('input'))
}
}
}
if (str[1].length == 1) {
e.target.value = e.target.value + "0";
e.target.dispatchEvent(new Event('input'))
}
if (str[1].length > 2) {
e.target.value = e.target.value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3');//只能输入两个小数
e.target.dispatchEvent(new Event('input'))
}
} else {
let arr = e.target.value.split("");
let res = arr.every((item, index) => {
return item == 0 || item == "0";
});
if (res) {
// e.target.value = "0.00";
} else {
e.target.value = e.target.value.replace(/\b(0+)/g, "") + ".00";
e.target.dispatchEvent(new Event('input'))
// e.srcElement.dispatchEvent(new Event('input'))
}
}
},
这里用
e.target.dispatchEvent(new Event(‘input’))
e.srcElement.dispatchEvent(new Event(‘input’))
都可以生效哈
其中的οninput=“value=value.replace(/[^0-9.]/g,‘’)”
输入非数字小数点会直接替换成空值 我估计他就是导致我明明页面输入值 保存时却报未填校验的元凶
我最终去掉了这个方法 改成用rules校验是否填写了数字
rules校验的正则
// 必须保留2位小数
export function mustTwoFigures (s) {
return /^(([1-9]{1}\d*)|(0{1}))(\.\d{2})$/.test(s)
}
如何抽出公共方法
main.js里
import utils from './utils/utils'
Vue.prototype.utils = utils
utils文件夹下的utils.js
export default { blur :方法 }
补0是直接用的上面那位大佬的方法 稍微改了下
只能输入两个小数 如果超过2位 会自动删除(这里注意下 tofixed也能保留两位小数 但似 他会四舍五入)
if (str[1].length > 2) {
e.target.value = e.target.value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3');
}