封装el-input组件,限制输入为指定的数值类,不符合提示(同样也适于表格动态添加行,单元格校验)
一、封装组件
<template>
<el-input
:class="['InputNumber', {inConformity: 'inConformity'}]"
v-bind="$attrs"
v-on="$listeners"
v-model="inputVal"
@input.native="inputHandle($event)"
@blur="blurHandle"
@change="onChange"
@keyup.enter.native="onKeyUpEnter"
ref="inputRef"
></el-input>
</template>
<script>
export default {
name: "InputNumber",
inheritAttrs: false,
props: {
// 输入框的值
fieldValue: {
default: "",
},
// 输入最大长度限制
maxlength: {
type: String,
default: '15',
},
// 是否为整数
isInteger: {
type: Boolean,
default: true,
},
// 每次输入后的回调
callback: {
type: Function,
default: null,
},
},
data() {
return {
inputVal: "",
originVal: "",
inConformity: false, // 不符合
isAdd: true
};
},
watch: {
// 监听外部值的改变
fieldValue: {
handler(val) {
this.originVal = this.inputVal = val;
},
immediate: true,
},
inputVal: {
handler(val) {
let isAccordWith = this.verifyNumber(val);
this.updateStatus(!isAccordWith);
},
immediate: true,
}
},
methods: {
updateStatus(inConformity){
this.inConformity = inConformity;
},
inputHandle(e) {
// 输入框为空时
if (e.target.value === "") {
this.originVal = "";
this.inputVal = "";
if (this.callback) this.callback("");
return;
}
let isAccordWith = this.verifyNumber(e.target.value);
if (isAccordWith) {
// 符合指定规则
if (this.isInteger || /^0+[^.]/.test(e.target.value)) {
// 是否格式化一下
this.inputVal = Number(e.target.value)
}
this.originVal = this.inputVal;
if (this.callback) this.callback(this.inputVal);
} else {
this.inputVal = e.target.value;
}
},
// 失焦去除数值末尾可能存在的.(浮点)
blurHandle() {
if (/\.$/.test(this.inputVal)) {
this.inputVal = Number(this.inputVal);
this.originVal = this.inputVal;
}
const val = this.inConformity ? this.inputVal : Number(this.inputVal);
this.$emit('update:fieldValue', val);
if(this.isAdd) {
this.$emit("blur");
this.isAdd = true;
} else {
this.onExitEdit();
}
},
onChange() {
if(this.inConformity) {
this.inputVal = this.originVal;
// 此处更改为自己需要的提示语句
this.$message.error("所输入的数据格式不对!");
this.isAdd = false;
} else {
if(this.isInteger) {
let isAccordWith = this.verifyMaxOrMin(this.inputVal);
if(!isAccordWith) {
// 此处更改为自己需要的提示语句
this.$message.error("所输入的数据范围不对!");
this.inputVal = this.fieldValue;
this.originVal = this.inputVal;
this.isAdd = false;
}
}
}
const val = this.inConformity ? this.inputVal : Number(this.inputVal);
this.$emit("update:fieldValue", val);
},
onExitEdit(){
this.$emit("onExitEdit");
},
onKeyUpEnter() {
this.blurHandle();
},
verifyNumber(val){
if(!val) return true;
let rule = /.*/;
if (this.isInteger) {
rule = /^[+-]?(\d+)$/;
} else {
rule = /^[+-]?(\d+|([1-9]\d+))(\.\d+)?$/;
}
return rule.test(val);
},
verifyMaxOrMin(num){
const max = Math.pow(2, 63);
const min = Math.pow(-2, 63);
return (min <= num) && (num <= max);
},
focus(){
this.$refs.inputRef.focus();
},
blur(){
this.$refs.inputRef.blur();
}
},
destroyed() {
this.isAdd = true;
}
};
</script>
<style lang="scss" scoped>
::v-deep .InputNumber {
.el-input__inner {
color: #606266;
border: none;
border-radius: 0;
}
}
.inConformity {
.el-input__inner {
color: red !important;
}
}
</style>
二、使用步骤
<template>
<div class="home">
<h1>This is an home page</h1>
<hr />
<InputNumber :fieldValue.sync="iptVal" />
<p>-----{
{
iptVal }}-----</p>
</div>
</template>
<script>
import InputNumber from "@/components/mycompo/InputNumber.vue";
export default {
name: "HomeView",
components: {
InputNumber,
},
data() {
return {
iptVal: "",
};
},
};
</script>