Vue 通用 表单验证器

不想用插件,用插件的好处是简单,方便谈不上,有时要定制就很麻烦,不好改
所以琢磨着写一个通用的 表单验证器
请教一下 vue 通用表单验证器的一般写法

最好有个例子,我可以参考一下


<script src="https://unpkg.com/vue@next" data-v="3"></script>
<style>
    .invalid{border-color:#f00}
</style>
<div id="app">
    <form v-formsubmit>
        <input v-required placeholder="不能为空" />
        <input v-regex data-regex="^\d+(\.\d+)?$" placeholder="只能填写数字" />
        <button @click="save" ref="btn">保存</button>
    </form>
</div>
<script>
    var config = {
        methods: {
            save() {
                setTimeout(() => {//需要延时下,click执行先于form绑定的submit事件
                    var valid = !this.$refs.btn.form.classList.contains('invalid')
                    console.log(valid)
                }, 0)

            }
        }
    };
    var app = Vue.createApp(config);
    app.directive('formsubmit', {//表单指令
        mounted(el) {
            el.addEventListener('submit', function (e) {
                e.preventDefault();//阻止表单提交
                var form = this;
                var error = false;
                var els = Array.from(form.querySelectorAll('.validate'));
                if (els.filter(i => i.classList.contains('invalid')).length) {//存在不通过的验证
                    form.classList.add('invalid');
                    return false;
                }

                //什么操作都没有,直接点击保存,触发下原生dom事件执行验证
                for (var el of els) {
                    for (var attr in el.dataset) {
                        var arr = attr.split('_');
                        if (!['HTMLEvents', 'MouseEvents'].includes(arr[0])) continue;
                        var event = document.createEvent(arr[0]);
                        event.initEvent(arr[1], true, false);
                        el.dispatchEvent(event);
                        if (el.classList.contains('invalid')) {
                            form.classList.add('invalid');
                            error = true;
                        }
                    }
                }

                if (!error)//全部验证通过,移除样式
                    form.classList.remove('invalid');

            });
        }
    });
    app.directive('required', {//必须填写数据指令
        mounted: function (el) {
            el.classList.add('validate');//添加过指令,给控件添加validate样式
            el.dataset.HTMLEvents_blur = true;//添加绑定事件,注意驼峰写法,以便表单验证时触发(HTMLEvents或者MouseEvents+_事件名【注意小写】)
            el.addEventListener('blur', () => {
                if (el.value.trim() == '') {
                    el.classList.add('invalid')
                }
                else el.classList.remove('invalid')
            })
        }
    });
    app.directive('regex', {//正则指令
        mounted: function (el) {
            el.classList.add('validate');//添加过指令,给控件添加validate样式
            el.dataset.HTMLEvents_blur = true;//添加绑定事件,注意驼峰写法,以便表单验证时触发(HTMLEvents或者MouseEvents+_事件名【注意小写】)
            var re = new RegExp(el.dataset.regex);
            el.addEventListener('blur', () => {
                if (!re.test(el.value)) {
                    el.classList.add('invalid')
                }
                else el.classList.remove('invalid')
            })
        }
    });
    app.mount('#app')
</script>

简单做了一个demo,完整的代码如下:


```html
<div id="app">
    <h2 class="login-h">登录</h2>
    <form :model="form" :rules="editFormRule" ref="form" @submit.prevent="subpass">
        <div>
            用户名:<input style="width:50%" v-model="form.username">
            </input>
        </div>
        <div>
            密码:<input style="width:50%" v-model="form.pwd" type="password"></input>
        </div>
        <div>
            确认密码:<input style="width:50%" v-model="form.surepwd" type="password"></input>
        </div>
        <div>
            <button type="submit">提交</button>
        </div>
    </form>
</div>
<style>
    * {
        color: #333
    }

    input {
        border: 1px solid #ccc;
    }
</style>
<script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
<script>
    new Vue({
        el: '#app',
        data() {
            //这里是自定义的规则
            var surepwdValid = (value, callback) => {
                if (!value) {
                    return (new Error('请输入确认密码'));
                } else if (value !== this.form.pwd) {
                    return (new Error('两次输入密码不一致!'));
                } else {
                    return false;
                }
            }
            return {
                form: {username:"",pwd:"", surepwd:""},
                editFormRule: {
                    username: {reg:/^\S+$/,message:"账号不能为空"},
                    pwd: {reg:/^\S{6,}$/,message:"密码不能少于6位"},
                    surepwd: { validator: surepwdValid},
                }
            }
        },
        methods: {
            subpass: function () {
                let rule = this.editFormRule;
                let form = this.form;
                for(var key in rule)
                {
                    if(rule[key].validator)
                    {
                        let result = rule[key].validator(form[key]);
                        if(result)
                        {
                            alert(result);
                            return false;
                        }
                    }
                    else if(rule[key].reg.test(form[key]) == false)
                    {
                        alert(rule[key]['message']);
                        return false;
                    }
                }
                alert('提交成功')
            }
        }
    })
</script>

```

要在Vue中实现通用表单验证器,可以创建一个可应用于表单输入的自定义指令。该指令可以根据指定的验证规则处理输入的验证。
以下是如何使用Vue自定义指令实现通用表单验证器的示例:

// Register the custom directive
Vue.directive('validator', {
  // The directive will be passed the validation rules as an argument
  bind: function (el, binding) {
    // Add a change event listener to the input
    el.addEventListener('change', function () {
      // Get the value of the input
      let value = el.value;

      // Loop through the validation rules
      for (let rule in binding.value) {
        // Check if the value of the input is valid based on the current rule
        if (!binding.value[rule].test(value)) {
          // If the value is invalid, add an error message to the input
          el.setCustomValidity(binding.value[rule].message);
          return;
        }
      }

      // If the value is valid, clear any error messages from the input
      el.setCustomValidity('');
    });
  }
});

new Vue({
  el: '#app',
  data: {
    // Define the validation rules for the form inputs
    rules: {
      username: {
        // The username must be at least 3 characters long
        pattern: /^.{3,}$/,
        message: 'The username must be at least 3 characters long.'
      },
      email: {
        // The email must be a valid email address
        pattern: /^\S+@\S+\.\S+$/,
        message: 'Please enter a valid email address.'
      }
    }
  }
});

在模板中,可以将v-validator指令应用于表单输入,并将验证规则作为参数传递。该指令将根据指定的规则处理输入的验证。

<form>
  <label>Username:</label>
  <input type="text" v-validator="rules.username" required>

  <label>Email:</label>
  <input type="text" v-validator="rules.email" required>

  <button type="submit">Submit</button>
</form>
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632