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>
相关推荐
kite01212 小时前
浏览器工作原理06 [#]渲染流程(下):HTML、CSS和JavaScript是如何变成页面的
javascript·css·html
крон2 小时前
【Auto.js例程】华为备忘录导出到其他手机
开发语言·javascript·智能手机
coding随想5 小时前
JavaScript ES6 解构:优雅提取数据的艺术
前端·javascript·es6
年老体衰按不动键盘5 小时前
快速部署和启动Vue3项目
java·javascript·vue
灵感__idea5 小时前
JavaScript高级程序设计(第5版):无处不在的集合
前端·javascript·程序员
星辰引路-Lefan5 小时前
深入理解React Hooks的原理与实践
前端·javascript·react.js
江城开朗的豌豆6 小时前
JavaScript篇:函数间的悄悄话:callee和caller的那些事儿
javascript·面试
江城开朗的豌豆6 小时前
JavaScript篇:回调地狱退散!6年老前端教你写出优雅异步代码
前端·javascript·面试
TE-茶叶蛋6 小时前
Vue Fragment vs React Fragment
javascript·vue.js·react.js
Angindem6 小时前
从零搭建uniapp项目
前端·vue.js·uni-app