输入框限制输入负数的方法,不能将输入框设置为type="number"类型的输入框,只能是type="text"的输入框,我尝试了很多次type="number"的输入框限制,结果都是以失败告终。不是中英文输入法出问题,就是不兼容移动端,pc可以限制输入负数,可是到了移动端一下子就不行了。

最后看了很多教程,写了一个通用的方式来处理这种限制。

一、核心代码:

挂载到vue原型上prototype请在main.js写。

/**
* 限制输入小数
* decimal:限制小数位。0:不允许输入小数点;-1:不限制;其他正整数。默认不限制。
* maxLength:限制最大长度。包含小数位和负号。默认值255
**/
Vue.prototype.prohibitNegative = function (value,decimal=-1, maxLength = 255) {
    if(!value){
        return value;
    }
    //限制输入小数点
    if(decimal==0){
        value = value.replace(/[`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/g, '').replace(/\s/g, "").replace("^[-]{0,1}\d+$","");
    }else{
        value = value.replace(/[`~!@#$%^&*()_\-+=<>?:"{}|,/;'\\[\]·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/g, '').replace(/\s/g, "").replace("^[-]{0,1}\d+$","");
    }
    //限制小数位
    if(decimal>0){
        let regex=new RegExp(`^\\d+(?:\\.\\d{0,${decimal}})?`,"g"); 
        value = (value && value.match(regex)[0]) || null;
    }
    //限制长度
    if(maxLength > 0 && value && value.length >= maxLength){
        value = value.slice(0,maxLength);
    }
    return value;
}

优化版本:

/**
* 限制输入小数
* decimal:限制小数位。0:不允许输入小数点;-1:不限制;其他正整数。默认不限制。
* maxLength:限制最大长度。包含小数位和负号。默认值255
**/
Vue.prototype.prohibitNegative = function (value,decimal=-1, maxLength = 255) {
    if(!value){
        return value;
    }
    if(value=='.' || value=='。'){
        return '';
    }
    value=value.replace("。",'.');
    //限制输入小数点
    if(decimal==0){
        value = value.replace(/[`~!@#$%^&*()_\-+=<>?:"{}|,./;'\\[\]·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/g, '').replace(/\s/g, "").replace("^[-]{0,1}\d+$","").replace(/[a-zA-Z]+/, '');
    }else{
        value = value.replace(/[`~!@#$%^&*()_\-+=<>?:"{}|,/;'\\[\]·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、]/g, '').replace(/\s/g, "").replace("^[-]{0,1}\d+$","").replace(/[a-zA-Z]+/, '');
    }
    //限制小数位
    if(decimal>0){
        let regex=new RegExp(`^\\d+(?:\\.\\d{0,${decimal}})?`,"g"); 
        value = (value && value.match(regex)[0]) || null;
    }
    //限制长度
    if(maxLength > 0 && value && value.length >= maxLength){
        value = value.slice(0,maxLength);
    }
    return value;
}

二、针对不同的框架使用方法:

element-ui:

以下代码element-ui框架,不能设置type="number",否则会出现输入负号后清空输入框,上面的函数已经禁止了中文和英文字符的输入,也就是最后一段replace函数:.replace("^[-]{0,1}\d+$","")。 

代码:

<el-input v-model="loginForm.userName" @input="e => loginForm.userName = prohibitNegative(e,2,10)"></el-input>

vant ui:

移动端必须设置type="number",否则字母或中文还是能输入。

<van-field type="number" v-model="form.amount" @input="e => form.amount = prohibitNegative(e,2,10)" placeholder="" />

iview:

不能使用。iview对input的封装不一样,只能手动封装一个输入框。

三、为什么有些UI框架不能使用呢?

我尝试了不同的框架,也看了很多UI框架的对input输入框实现的源码,很多UI框架对input输入框的封装不一样。

iview采用的是动态绑定属性的方式设置input的值,我刚开始也是这种方式封装的原生输入框,效果也跟iview的一样,不生效,输入框的值出现异常:

总结:input输入框封装的时候,如果采用的是属性绑值(:value="value")的形式,那么在使用这个封装输入框的时候,触发后的input事件无效,要么就是第一次生效。

如果我们遇到了这种情况,安装了iview框架,知道了该怎么解决,但是我们却改不了iview的代码,最好的方式是自己封装一个输入框。

封装输入框:


<template>
 <div>
     <!--能输入负号-->
    <input :value="value" :type="type" :placeholder="placeholder" @keypress="keypress" @keydown="keydown" @input="input" @change="change" @blur="blur" ref="input" class="ex-input ex-input-large ex-input-max" />
 </div>
</template>

<script>
export default {
    name: '',
    model:{
        prop:'value',
        event:'input'
    },
    props: {
        //输入框的值
        value:{
            type:[String,Number],
            default:''
        },
        //输入框的类型
        type:{
            type:String,
            default:'text'
        },
        //最大长度
        maxLength:{
            type:[String,Number],
            default:0
        },
        //默认字符
        placeholder:{
            type:String,
            default:''
        },
        //是否能输入负号,负数
        isNegative:{
            type:Boolean,
            default:true
        },
        //限制小数位,-1值不生效,0以上的生效
        decimal:{
            type:[Number],
            default:0
        }
    },
    components: {

    },
    data () {
        return {

        }
    },
    mounted() {
        this.setNativeInputValue();
    },
    methods: {
        //获取input实例
        getInput() {
            return this.$refs.input;
        },
        //选择输入框内容
        select() {
            this.getInput().select();
        },
        //原生操作dom修改值
        setNativeInputValue() {
            const input = this.getInput();
            input.value = this.value;
        },
        //按键
        keypress(e){
        },
        //按上
        keydown(e){
        },
        //输入事件
        input(e){
            if(e.target.value){
                //限制长度
                if(this.maxLength > 0 && e.target.value.length >= this.maxLength){
                    e.target.value = e.target.value.slice(0,this.maxLength);
                }
            }
            this.$emit("input",e.target.value);
            this.$nextTick(this.setNativeInputValue);
        },
        //输入改变,并失去焦点
        change(e){
            this.$emit("change",e.target.value);
        },
        //失去焦点
        blur(e){
            this.$emit("blur",e.target.value);
        }
    },
    watch:{
        value() {
            this.setNativeInputValue();
        },
    }
}
</script>

<style scoped lang='less'>
.ex-input {
    display: inline-block;
    width: 100%;
    height: 32px;
    line-height: 1.5;
    padding: 4px 7px;
    font-size: 14px;
    border: 1px solid #dcdee2;
    border-radius: 4px;
    color: #666;
    background-color: #fff;
    background-image: none;
    position: relative;
    cursor: text;
    transition: border 0.2s ease-in-out, background 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
}
.ex-input-large {
    font-size: 16px;
    padding: 6px 7px;
    height: 40px;
}
.ex-input-max {
    background-color: #111;
    border-color: transparent;
    color: #c8c7d8;
    caret-color: #c8c7d8;
}
.ex-input::-webkit-input-placeholder {
    color: #c8c7d8;
}
/*去掉上下箭头*/
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}

input[type="number"] {
-moz-appearance: textfield;
}
</style>

Logo

前往低代码交流专区

更多推荐