v-input-limit

javascript 复制代码
/*

    v-input-limit:price             金额

    v-input-limit:phone             电话

    v-input-limit:number            数字

    v-input-limit:negativePrice     负数金额

    v-input-limit:loginVerify       登录验证码

    v-input-limit:verify            短信验证码

    v-input-limit:idCard            身份证号

    v-input-limit="RegExp"          自定义验证规则

*/

export default {

    // 该指令会频发触发input事件,并且ctrl+z会失效,使用时请注意

    inserted(el, binding, vnode) {

        // 通过修饰符储备可用的正则

        const regObj = {

            price: /^(\d*|(\d+\.\d{0,2}))$/,

            phone: /^\d{0,11}$/,

            number: /^\d*$/,

            negativePrice: /^\-?(\d*|(\d+\.\d{0,2}))$/, //负数金额

            loginVerify: /^[0-9a-zA-Z]{0,4}$/,

            verify: /^\d{0,6}$/,

            idCard: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,//身份证号(15位、18位数字),最后一位是校验位,可能为数字或字符X

            allphone: /^[0-9\+\-]{0,14}$/ //电话+手机

        }

        // 要应用的正则表达式 优先binding.value

        let reg =

            binding.value && binding.value instanceof RegExp

                ? binding.value

                : binding.arg && regObj[binding.arg] ? regObj[binding.arg] : null


 

        // input输入事件

        el._inputHandle = function (e) {

            // 判断是否是用户行为

            if (

                e.isTrusted &&

                !(

                    !e.isComposing &&

                    e.inputType === 'insertCompositionText' && e.data

                )

            ) {

                // 判断正则匹配

                let isFalse = reg && !reg.test(e.target.value)

                // 如果匹配错误返回上次输入值

                el._input = isFalse ? el._input : e.target.value

                e.target.value = '' //重置中文输入法

                e.target.value = el._input // 重新赋值

                // 控制光标所在位置

                if (isFalse) {

                    // 输入内容不匹配,光标不动

                    e.target.selectionStart = el._start

                    e.target.selectionEnd = el._end

                } else {

                    // 判断inputType计算光标位置

                    // inputType类型 https://www.jc2182.com/javascript/javascript-html-dom-inputtype-event-attr.html

                    switch (e.inputType) {

                        case 'deleteContentForward': //delete

                        case 'deleteByDrag': //dropout

                        case 'deleteByCut': //cut

                            e.target.selectionStart = el._start

                            e.target.selectionEnd = el._start

                            break

                        case 'deleteContentBackward': //backspace

                            e.target.selectionStart =

                                el._start === el._end

                                    ? el._start - 1

                                    : el._start

                            e.target.selectionEnd =

                                el._start === el._end

                                    ? el._start - 1

                                    : el._start

                            break

                        case 'insertFromPaste': //粘贴

                        case 'insertFromDrop': //拖入

                            let dataTransfer =

                                e.dataTransfer ||

                                e.clipboardData ||

                                null

                            if (dataTransfer) {

                                let txt =

                                    dataTransfer.getData('text') || ''

                                e.target.selectionStart =

                                    el._start + txt.length

                                e.target.selectionEnd =

                                    el._start + txt.length

                            }

                            break

                        case 'insertText': //insert

                        case 'insertCompositionText': //中文输入法输入

                            e.target.selectionStart = el._start + 1

                            e.target.selectionEnd = el._start + 1

                            break

                        default:

                            break

                    }

                }

                // 发送input事件同步字符串

                let event = new InputEvent('input', {

                    isComposing: false,

                })

                e.target.dispatchEvent(event)

                // 中文下触发el-input input事件

                // if (e.isComposing) {

                //     // 中文时同步字符串--表示内容以输入完毕

                //     let event = new CompositionEvent('input', {

                //         isComposing: false,

                //         data: ''

                //     })

                //     e.target.dispatchEvent(event)

                //     console.log

                // } else {

                //     // 同步字符串

                //     let event = new InputEvent('input')

                //     e.target.dispatchEvent(event)

                // }

            } else {

                return

            }

        }

        // input输入前事件

        el._beforeinputHandle = function (e) {

            el._input =

                reg && !reg.test(e.target.value) ? '' : e.target.value

            el._start = e.target.selectionStart

            el._end = e.target.selectionEnd

        }

        // input以及el-input可使用本指令

        if (

            vnode.tag === 'input' ||

            (vnode.componentOptions &&

                vnode.componentOptions.tag === 'el-input')

        ) {

            // 监听input事件

            el.addEventListener('input', el._inputHandle)

            // 监听inputbefore事件 给el._input赋值(未知的兼容性)

            el.addEventListener('keydown', el._beforeinputHandle)

            // 阻止事件传播(firefox)

            el.addEventListener('drop', e => {

                e.stopPropagation()

            })

        } else {

            console.warn('该指令应应用于input或el-input')

        }

    },

    unbind(el, binding) {

        // 取消事件绑定

        el._inputHandle &&

            el.removeEventListener('input', el._inputHandle)

        el._beforeinputHandle &&

            el.removeEventListener('beforeinput', el._beforeinputHandle)

    }

}

在main.js中全局注册

javascript 复制代码
//引入自定义指令
import * as directives from "./directives";
//注册指令
Object.keys(directives).forEach((k) => Vue.directive(k, directives[k]));

组件中直接使用

javascript 复制代码
<el-input
                      v-model.trim="item.giveHour"
                      placeholder="请输入"
                      clearable
                      v-inputLimit:number
                    >
                    </el-input>
相关推荐
聪明的墨菲特i25 分钟前
VUE组件学习 | 六、v-if, v-else-if, v-else组件
前端·vue.js·学习·前端框架·vue
木子七1 小时前
Js内建对象
前端·javascript
Front思2 小时前
根据输入的详细地址解析经纬度
前端·javascript
洪大宇2 小时前
Vuestic 整理使用
开发语言·javascript·ecmascript
zqwang8882 小时前
Performance API 实现前端资源监控
前端·javascript
我看刑2 小时前
el-datepicker此刻按钮点击失效
javascript·vue.js·ecmascript
HC182580858322 小时前
零基础学西班牙语,柯桥专业小语种培训泓畅学校
前端·javascript·vue.js
图扑软件2 小时前
掌控物体运动艺术:图扑 Easing 函数实践应用
大数据·前端·javascript·人工智能·信息可视化·智慧城市·可视化
好青崧3 小时前
JavaScript 循环与条件判断
开发语言·javascript·udp