element-ui :封装el-input 遇到的问题

这篇具有很好参考价值的文章主要介绍了element-ui :封装el-input 遇到的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

因项目中有多处输入框要求只能输入整数或者浮点数, el-input 设置type=number 火狐浏览器这个属性是无效的; 所以就想到了 使用el-input type=text 输入的时候 正则匹配, 只能输入整数或者浮点数; 所以为了方便使用,需要对第三方库el-input 进行封装。

1. 初始封装的组件Number-input.vue 代码如下:

<template>
    <el-input 
    :value="value" 
    v-bind="$attrs"
    type="text" 
    @input="handleInput"
    />

</template>
<script>
import Big from 'big.js';
    export default {
        inheritAttrs: false,
        props: {
            value: {
                type: String | Number,
                default: ''
            },
            precision: {
                type: Number,
                validator(val) {
                    return val >= 0 && val === parseInt(val, 10);
                }
            },
            minPrecision: {
                type: Number,
                validator(val) {
                    return val >= 0 && val === parseInt(val, 10);
                }
            },
            maxPrecision: {
                type: Number,
                default: Infinity,
                validator(val) {
                    return val >= 0 &&(val === parseInt(val, 10) || val === Infinity);
                }
            },
            isNumber: {
                type: Boolean,
                default: false
            },
            max: {
                type: String | Number,
                default: Infinity
            },
            min: {
                type: String | Number,
                default: -Infinity
            }
        },
        methods: {
            handleInput(val) {
                console.log('ssssss===', val)
                let reg = ''
                if(this.maxPrecision === Infinity) {
                    // this.$emit('input', val)
                   reg  = new RegExp(`^\\D*(\\d*(?:\\.\\d{0,20})?).*$`, 'g')
                    this.$emit('input', val.replace(reg ,'$1'))
                } else if(this.maxPrecision >= 0) {
                    //  正则不能输入最大位数
                   reg  = new RegExp(`^\\D*(\\d*(?:\\.\\d{0,${this.maxPrecision}})?).*$`, 'g')
                    this.$emit('input', val.replace(reg ,'$1'))
                }
                val = val.replace(reg ,'$1')
                this.$emit('input', val)
                console.log('ssssss结束===', val)
            },
            handleInputChange(val) {
                console.log('handleInputChange====',  val, this.precision)
                let newV = isNaN(val) ? '' : (val ? val.toString() : '')
                if(newV) {
                    newV = this.getNewValue(val.toString())
                }
                this.$emit('input', newV)
            },
            getNewValue(val) {
                // 根据精度获取幂次数, 获取精度整数位 利用math.round 四舍五入  转成float类型 再除以相同的10次幂 1.345直接利用tofixed(2) 取2位精度 会有问题 
                let newV = ''
                let bigNewV = new Big(val)
                let precisionArray = val.split('.')
                let precision = precisionArray?.[1]?.length??0
                if(this.minPrecision >= precision) {
                    newV = bigNewV.toFixed(this.minPrecision)
                } else {
                    newV = bigNewV.toFixed(precision)
                }
                return newV
            }
        }
    
    }
</script>

封装第三方组件主要用到 $atrrs 和 $listeners 

v-bind="$attrs" v-on="$listeners" 

 $atrrs:接收父组件传过来的非class 和 style , 并且未在props  中注册使用的属性 

$listeners :接收父组件传过来的非native 的事件

(注:.native 事件是父组件本身的事件, 在vue 中.native 只能用于组件上,.native 修饰符的作用是:在一个组件的根元素上直接监听一个原生事件; 原生的标签上不能使用 比如直接在<input @input.native='xxx' /> 会报错)

2. 父组件 Add.vue  中使用

 <NumberInput 
:maxPrecision="0" 
v-model="quantity" 
placeholder="请输入" 
clearable />

 上述使用目前为止都是正常的;

然后突然发现另外一个同事使用的时候 ,出现了问题!!!

在封装的组件Number-input.vue中多写一个属性为了接收父组件传过来的事件再传给下一级:v-on="$listeners"

<template>
    <el-input 
    :value="value" 
    v-bind="$attrs"
    v-on="$listeners"
    type="text" 
    @input="handleInput"
    />

</template>

和上述对比 导致除了数字其他还能输入

原因就是 el-input 源码中 通过 v-on="$listeners" 接收了 业务组件Add.vue 传过来的事件, Add.vue 使用v-model 实现双向绑定, 默认有一个input 事件; 所以 当输入框输入数据的时候 , el-input 源码 中 触发input 事件, 同时向外触发 this.$emit('input', event.target.value) , 这个会先后触发Number-input.vue 和 Add.vue 中的 input事件; Add.vue中默认的input 事件接收的是 el-input 源码中传过来的原始值,会覆盖掉 Number-input.vue 中传过来的值, 最终v-model 中的值接收的也是el-input 源码中传过来的原始值. 

el-input 源码
handleInput(event) {
        // should not emit input during composition
        // see: https://github.com/ElemeFE/element/issues/10516
        if (this.isComposing) return;

        // hack for https://github.com/ElemeFE/element/issues/8548
        // should remove the following line when we don't support IE
        if (event.target.value === this.nativeInputValue) return;
        console.log('el-input input事件====', event)

        this.$emit('input', event.target.value);

        // ensure native input value is controlled
        // see: https://github.com/ElemeFE/element/issues/12850
        this.$nextTick(this.setNativeInputValue);
      },

知道了原因所在,如何修复该问题:

1. Number-input 组件中的@input 和 @change事件 添加.native , 这样的话 el-input 源码中的 $emit('input' 就不会触发这两个事件 ; 这两个事件 会添加到 组件的根元素上 ; 看 el-input 源码可知 会添加到最外层的div 上; 然后 当我们输入数据的时候 ,首先$emit('input' 触发的是Add.vue 中的input 事件改变value 值;接着 通过冒泡 会触发父元素上的input 和 change事件, 在这 两个事件中 手动又去触发了 add.vue 中的input 事件(这个主要是自己怎么写), 改变了 value 值, 最终改了输入框的值

2. Number-input.vue中监听value 值的变化 类似下面: 但是这种 不能 区分是input 还是change事件文章来源地址https://www.toymoban.com/news/detail-436664.html

watch: {
            value: {
                handler(val, oldV) {
                    let reg = ''
                    if(this.maxPrecision === Infinity) {
                        // this.$emit('input', val)
                    reg  = new RegExp(`^\\D*(\\d*(?:\\.\\d{0,20})?).*$`, 'g')
                        this.$emit('input', val.replace(reg ,'$1'))
                    } else if(this.maxPrecision >= 0) {
                        //  正则不能输入最大位数
                    reg  = new RegExp(`^\\D*(\\d*(?:\\.\\d{0,${this.maxPrecision}})?).*$`, 'g')
                        this.$emit('input', val.replace(reg ,'$1'))
                    }
                    val = val.replace(reg ,'$1')
                    this.$emit('input', val)
                }
            }
        },

到了这里,关于element-ui :封装el-input 遇到的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Element UI 中el-input 框回车触发页面刷新问题及解决

    问题描述 当el-input 获取焦点后按到回车按钮会刷新当前页面 问题解决 在el-form标签增加表单事件@submit.native.prevent,防止搜索框回车键刷新整个页面

    2024年02月09日
    浏览(41)
  • 解决:element ui表格表头自定义输入框单元格el-input不能输入问题

    表格表头如图所示,有 40-45,45-50 数据,且以输入框形式呈现,现想修改其数据或点击右侧加号增加新数据编辑。结果不能输入,部分代码如下 我看在这一块 template 中不需要用到 scope 去获取数据,于是没有加上 slot-scope=\\\"scope\\\" 结果不能输入,解决方法就是在表头自定义时将

    2024年02月03日
    浏览(43)
  • 解决使用element ui时el-input的属性type=number,仍然可以输入e的问题。

    使用element ui时el-input的属性type=number,仍然可以输入e, 其他的中文特殊字符都不可以输入,但是只有e是可以输入的,原因是e也输入作为科学计数法的时候,e是可以被判定为数字的, 但是有些场景是需要把e这种情况屏蔽掉的,我们可以使用如下的方法。 在进行键盘事件输入

    2024年02月08日
    浏览(35)
  • element ui中的el-input回车键事件

    今天项目里面的登录页面,需要按键盘回车键就直接登录,但是测试的时候,按了回车键后,直接刷新页面了,这不是我想要的,之后网上查了一下 代码如下: 上面的写法没问题,但是这样又会出现一个问题,当form表单中只有一个input框时,按回车键,页面还是刷新的。 之

    2024年02月11日
    浏览(51)
  • Element UI el-input 只能输入大于0的正整数

    当输入值以0开头或者不为0-9的整数时,则用\\\' \\\'替换掉(/g表示全局匹配,则所有匹配项都会被替换掉),效果为不能输入以0开头或不为正整数的值。

    2024年02月14日
    浏览(44)
  • element ui el-input输入框type=number去掉上下箭头

    使用vue框架写法 如果是input标签type=number,将上述css代码中 ::v-deep 去掉即可

    2024年02月12日
    浏览(40)
  • Element UI 中 el-input 标签去掉边框的一种办法

    最近在做一个简单的页面,想把 el-input 去掉边框,在网上找了很多方法,最终发现下边这种方法是可行的: HTML代码: 样式代码如下: 注意这里的样式语言用的是 less,其深度穿透写法是 /deep/。 由此便可去除 el-input 的外边框。

    2024年02月16日
    浏览(33)
  • element-ui问题合集(el-input-number加减一次就失效,el-select同时收集id与name)

    将id与name拼接成字符串,赋值给value,在使用时,获取value后,再使用split()方法进行分割 将el-input-number的v-model绑定对象之后,发现加减一次后就失效  

    2024年02月07日
    浏览(38)
  • Element plus中el-input 框回车触发页面刷新问题及解决方案

    技术:vue3+element plus的UI框架 今天做了一个小小的功能,就是基于elementUi框架的一个输入框,需要监听输入框的回车事件,然后调取接口。 代码如下: 在输入框回车后会刷新页面,查询的原因如下 在 el-form 里加上 @submit.prevent , input输入框里可以使用 @keyup.enter 监听回车事件

    2024年02月15日
    浏览(43)
  • 【踩坑笔记】vue3 element-plus el-input 无法输入问题

    原因是 el-form 的 v-model=\\\"loginForm\\\" ref=\\\"loginForm\\\" 在vue3中值不能相同 把ref去掉或者改名即可 这是js的代码( 对象记得用reactive,不然也会无法输入 ) 这个是可以输入的 这是无法输入的 就改了个ref

    2024年02月11日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包