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>
相关推荐
冰暮流星2 分钟前
javascript之回调函数
开发语言·前端·javascript
wuhen_n10 分钟前
Vue3 组件中的图片懒加载与渐进式加载
前端·javascript·vue.js
叫回忆10 分钟前
elpis的npm抽离与发布
前端·javascript
wuhen_n18 分钟前
Vite 构建层面的图片优化:从压缩到转换
前端·javascript·vue.js
Irene199118 分钟前
Vue3 的 Proxy 与 Vue2 的 Object.defineProperty 的对比
vue.js·proxy·defineproperty
hashiqimiya19 分钟前
vue项目组装-路由-文件修改地方
前端·javascript·vue.js
回到原点的码农29 分钟前
TypeScript 与后端开发Node.js
javascript·typescript·node.js
@yanyu66639 分钟前
04vue3基础
前端·javascript·vue.js
SuperEugene1 小时前
Vue3 Props 传参实战规范:必传校验 + 默认值 + 类型标注,避开 undefined / 类型混用坑|Vue 组件与模板规范篇
前端·javascript·vue.js·前端框架
吴声子夜歌1 小时前
JavaScript——数组
java·javascript·算法