添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
·  阅读 10分钟实现一个Vue的input纯数字组件

事件的起因是我在几个项目中多次碰到了input组件限制输入纯数字的需求,之前只能在方法里面各种使用正则,一顿猛如虎的操作下干巴巴地实现了需求。这次我决定正视它,刚好把js正则的基础使用一并学习下。相信我遇到的以下需求,各位应该都能经常碰到。 因为这个功能比较常见,需要重复利用,遂封装成为了一个组件,下面贴出👶组件核心代码:

const vm = new Vue({
    el: '#app',
    data: {
    	msg: '输入框限制只能输入数字,并且对小数点后可以输入几位做限制',
      	pureNum: '', // 纯数字
    // 自定义一个组件
    components: {
        'custom-input': {
            props: {
                // 默认值
                defaultNum: {
                    type: String,
                    deafault: ''
                // 是否正整数
                isInt: {
                    type: Boolean,
                    default: true
                // 小数点后保留几位
                keepPoint: {
                    type: Number,
                    default: 2
            data() {
                return {
                    inputVal: this.defaultNum
            methods: {
                // 在 Input 值改变时触发
                handleInput(val,event) {
                    if (this.isInt) {
                        // \D 查找非数字字符 n+ 匹配任何包含至少一个n的字符串
                        // 匹配任何包含至少一个非数字字符的字符串
                        let value = event.target.value.replace(/\D+/,'')
                        this[val] = value
                    } else {    
                        /* 1.匹配必须要是数字(任何包含至少一个数字) \d 查找数字 
                         * 2.匹配只包含小数点零个或者一个以内 n? 匹配任何包含零个或一个n的字符串
                         * 3.匹配零个或多个数字的字符串  n* 匹配任何包含零个或多个n的字符串 */
                        // 在字符串内检索指定的值 返回值是存放匹配结果的数组
                        let matchArr = event.target.value.match(/\d+\.?\d*/)
                        this[val] = matchArr ? matchArr[0] : ''
                        // 保留小数点还要判断 因为如果定义了isInt:false也可以输入正整数
                        let str = String(this[val])
                        if (this.keepPoint) {
                            if (str.includes('.')) {
                                // 例如数据为 123.4567 ==> 123.45
                                /* 1.通过 indexOf('.')找到包含小数点位置的索引值
                                 * 2.读取几位从这个索引值的位置开始+(.xx)共三位数|+(.xxx)共四位数
                                 * 3.string.indexOf('.') + length + 1 substr(start,length) */
                                this[val] = str.substr(0,str.indexOf('.')+(this.keepPoint+1))
                            } else {
                                // 此处控制的是如果没有小数点,首位不能为类似于 01、02的金额
                                if (str != '') {
                                    this[val] = String(parseFloat(this[val]))
                    // this[val] 其实就是 inputVal
                    this.$emit('update',this[val])
            // 下面只不过利用的是elementUI的输入框的样式 因为原生的input事件默认的参数就是事件对象
            // 如果传入多个参数的话 事件对象放在最后
            template: `
                    <input class="el-input__inner"
                        v-model="inputVal"
                        @input="handleInput('inputVal', $event)"
                        placeholder="请输入上面要求的数字"
                    </input>
                    <p>{{inputVal}}</p>

应用到👨组件时候的代码:

<div id="app">
    <!-- 当使用的不是字符串模板时,驼峰式命名的prop(js中命名的)在html中使用时要转换成kebab-case -->
    <el-card style="width: 50%;">
        <custom-input
            :default-num="pureNum"
            @update="pureNum = $event"
            :is-int="false"
            :keep-point="2"
        </custom-input>
    </el-card>

真正实现功能的代码量其实并不多,我很喜欢写注释,只要感觉有点不懂的就记下来,努力做到注释比代码多~

分类:
前端
标签: