使用vue自定义指令开发表单验证插件validate.js

这段时间在进行一个新项目的前期搭建,新项目框架采用vue-cli3和typescirpt搭建。因为项目比较轻量,所以基本没有使用额外的ui组件,有时候我们需要的一些基础组件我就直接自己开发了。今天就来介绍一下如何利用vue的自定义指令directive来开发一个表单验证插件的过程。

1.vue插件开发

关于vue的插件开发,官方文档里有很清晰的说明,详情可以去阅读开发文档。我自己开发的表单验证插件validate.ts和loading,messageBox插件都是利用了这种方式。今天先来看表单验证插件的开发。

vue全局指令

// myPlugin.js export default { install: (Vue, options) => { // 注册一个my-directive指令 Vue.directive('my-directive', { bind(el, binding, vnode, oldVnode) { // 逻辑 } ... }) } } // main.js import Vue from 'vue'; import myPlugin from 'myPlugin'; Vue.use(myPlugin);

上面是注册一个vue指令插件的写法。值得注意的是注册自定义指令的时候,bind()函数为指令的钩子函数,其中的参数el表示指令绑定的元素,可以直接操作DOM。binding表示一个对象,包括指令名称,绑定值等信息。vnode和oldVnode表示Vue编译生成的虚拟节点。

我们通过注册一个全局指令v-validateParams指令,绑定到输入表单的input标签上来校验当前输入值是否符合要求。

2.v-validateParams指令

最开始我参考了网上的一些代码。基础的实现如下:

整体框架

import Vue from 'vue' export default { install: (Vue, options) => { // 注册一个全局自定义指令 `v-validateParams` Vue.directive('validateParams', { // 当被绑定的元素插入到 DOM 中时 inserted: function (el, binding, vNode) { // 给指令绑定的Dom元素添加事件监听,监测输入框失焦事件 // 每次当表单中的输入框失焦时执行函数 el.addEventListener('blur', function (event) { // 1.首先重置所有错误提示 // 2.获取自定义指令中传入的校验规则参数和表单输入的值 // 3.依次判断当前输入的值是否符合校验规则 }) } }) // 注册一个全局自定义指令 `v-validateSubmit`,这个指令绑定到表单的提交button上 Vue.directive('validateSubmit', { // 当被绑定的元素插入到 DOM 中时 inserted: function (el, binding, vNode) { // 给提交button添加事件监听 el.addEventListener('click', function (event) { // 获取当前组件内所有含有v-check类名的元素 let elements = vNode.context.$el.getElementsByClassName('v-check') var evObj = vNode.context.$el.createEvent('Event') evObj.initEvent('blur', true, true) for (let element of elements) { // 给所有v-check元素绑定blur事件 element.dispatchEvent(evObj); } // 获取当前组件下的所有错误提示元素 let errorInputs = vNode.context.$el.getElementsByClassName('input-error'); // 如果组件中没有错误提示元素,则执行当前组件实例中的submit()函数 if(errorInputs.length === 0){ vNode.context.submit(); } }) } }) } }

这里需要着重说明一下 validateSubmit 指令,这个指令绑定到提交按钮上,在点击的时候执行校验,校验通过之后执行提交操作。但是这里的实现方式不是特别友好:

1.需要获取当前组件中的所有input元素,给他们绑定并执行 blur 事件,以此来执行 validateParams 指令中的校验逻辑。

2.需要获取当前组件中的所有错误提示元素,如果他们存在就不能执行提交操作。

3.当组件内不含任何错误提示元素时,就表示校验通过,执行当前组件内的 submit 函数,所以每个表单组件的提交函数都只能命名为 submit

然后我们再看下指令 validateParams ,该指令需要绑定到表单 input 元素上,并把校验规则当作参数写入。当该input元素失焦时,会执行指令中给当前元素绑定的事件中的逻辑。这些逻辑分为三个步骤,我已经写在注释里了,现在我们来看下具体实现。

重置所有错误提示

/** * 重置当前节点样式 * @param el: HTMLElement,传入当前绑定的input元素 */ const resetError = (el: HTMLElement) => { el.className = el.className.replace('input-error', '').trim(); if ( el.parentNode ) { const ErrorNode = el.parentNode.querySelector('.error-tips'); if (ErrorNode) { el.parentNode.removeChild(ErrorNode); } } };

获取自定义指令中传入的校验规则参数和表单输入的值

// binding.value是传入自定义指令的参数,以数组的形式 for (const rule of binding.value) { // 分别获取到自己定义的校验规则并执行 const { min, max, message, required, pattern } = rule; if ( min && InputEl.value.length < min ) { // 如果不符合校验,执行报错函数 validateError(InputEl, message); break; } if ( max && InputEl.value.length > max ) { validateError(InputEl, message); break; } if ( !!required && !InputEl.value ) { validateError(InputEl, message); break; } if ( pattern && !pattern.test(InputEl.value) ) { validateError(InputEl, message); break; } if ( rule && typeof rule === 'function' ) { rule(vNode.context, InputEl.value, validateError, InputEl); break; } }

校验不符合,执行报错函数

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/c297383291ca241133e788398de1407e.html