手撸一个类似 Laravel 验证器的表单验证器

113 阅读2分钟

介绍

Laravel 的表单验证很方便,想在前端也用这样的方式进行验证。

git 地址,欢迎star

期待这个表单验证库有这样的功能。

                                                      try {
                                                          validator.validate()
                                                          } catch(e) {
                                                              uni.showToast({
                                                                      icon: 'error',
                                                                              title: e.message
                                                                                  })
                                                                                  }" aria-label="复制" data-bs-original-title="复制">
                      <i class="far fa-copy"></i>
          </button>
</div>
      </div><pre class="javascript hljs language-javascript"><span class="hljs-keyword">let</span> validator = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Validation</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">registerForm</span>, {
          <span class="hljs-attr">telephone</span>: <span class="hljs-string">"required|telephone"</span>,
              <span class="hljs-attr">captcha</span>: <span class="hljs-string">"required|length:5"</span>,
              }, {
                  <span class="hljs-attr">telephone</span>: {
                          <span class="hljs-attr">required</span>: <span class="hljs-string">"手机号不能为空"</span>,
                                  <span class="hljs-attr">telephone</span>: <span class="hljs-string">"手机号格式不正确"</span>,
                                      },
                                          <span class="hljs-attr">captcha</span>: <span class="hljs-string">"验证码不正确"</span>
                                          })
                                          
                                          <span class="hljs-keyword">try</span> {
                                              validator.<span class="hljs-title function_">validate</span>()
                                              } <span class="hljs-keyword">catch</span>(e) {
                                                  uni.<span class="hljs-title function_">showToast</span>({
                                                          <span class="hljs-attr">icon</span>: <span class="hljs-string">'error'</span>,
                                                                  <span class="hljs-attr">title</span>: e.<span class="hljs-property">message</span>
                                                                      })
                                                                      }</pre><p>构造函数的第三个参数 messages 可以不要,默认是英文提示。而且该参数支持不同粒度的错误信息,如果传对象,则如果对应的规则校验不通过,就使用对应的错误信息;如果传字符串,则不论什么规则未通过,都使用该错误信息。</p><p>内置一些规则,如果不够用,还可以自己扩展。</p><p>根据以上的需求,就有了这个库 <code>@church1117/form-validation</code>。</p><h3 id="item-0-2">安装</h3><div class="widget-codetool" style="display: none;">
      <div class="widget-codetool--inner">
                  <button type="button" class="btn btn-dark rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="npm install @church1117/form-validation" aria-label="复制" data-bs-original-title="复制">
                      <i class="far fa-copy"></i>
          </button>
</div>
      </div><pre class="shell hljs language-shell">npm install @church1117/form-validation</pre><h3 id="item-0-3">使用</h3><div class="widget-codetool" style="display: none;">
      <div class="widget-codetool--inner">
                  <button type="button" class="btn btn-dark rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="import Validation from &quot;@church1117/form-validation&quot;
                  
                  let data = {
                          name: &quot;church&quot;,
                                  mobile: &quot;18565919379&quot;,
                                          age: 19,
                                                  gender: '2',
                                                          password: &quot;123456&quot;,
                                                                  captcha: &quot;12345&quot;,
                                                                          idcard: '42052919910727452X',
                                                                                  email: &quot;xxx@qq.com&quot;,
                                                                                          test: &quot;ttt&quot;,
                                                                                                  birthday: '1993/11/17',
                                                                                                      }
                                                                                                      
                                                                                                      let rules = {
                                                                                                              name: &quot;required|between:6,255&quot;,
                                                                                                                      mobile: &quot;required|telephone&quot;,
                                                                                                                              age: &quot;numeric|between:8,60&quot;,
                                                                                                                                      gender: &quot;numeric|range:&quot; + gender.join(','),
                                                                                                                                              password: &quot;required|min:6|password&quot;,
                                                                                                                                                      captcha: &quot;required|length:5&quot;,
                                                                                                                                                              idcard: &quot;required|idcard&quot;,
                                                                                                                                                                      email: &quot;email&quot;,
                                                                                                                                                                              // test: &quot;required|testRule&quot;
                                                                                                                                                                                      birthday: &quot;datetime&quot;
                                                                                                                                                                                          }
                                                                                                                                                                                          
                                                                                                                                                                                          let messages = {
                                                                                                                                                                                                  name: {
                                                                                                                                                                                                              required: &quot;名字不能为空&quot;,
                                                                                                                                                                                                                          between: &quot;名称长度必须在6~255之间&quot;,
                                                                                                                                                                                                                                  },
                                                                                                                                                                                                                                          mobile: &quot;不正确的手机格式&quot;,
                                                                                                                                                                                                                                                  age: {
                                                                                                                                                                                                                                                              numeric: &quot;年龄不是一个有效的数值&quot;,
                                                                                                                                                                                                                                                                          between: &quot;年龄必须在18-60岁之间&quot;
                                                                                                                                                                                                                                                                                  },
                                                                                                                                                                                                                                                                                          password: {
                                                                                                                                                                                                                                                                                                      required: &quot;密码不能为空&quot;,
                                                                                                                                                                                                                                                                                                                  min: &quot;密码长度不能小于6位&quot;,
                                                                                                                                                                                                                                                                                                                              regex: &quot;密码只能由数字、大小写字母构成&quot;,
                                                                                                                                                                                                                                                                                                                                      },
                                                                                                                                                                                                                                                                                                                                              captcha: &quot;验证码不正确&quot;,
                                                                                                                                                                                                                                                                                                                                                      idcard: {
                                                                                                                                                                                                                                                                                                                                                                  required: &quot;身份证不能为空&quot;,
                                                                                                                                                                                                                                                                                                                                                                              idcard: &quot;身份证格式不正确&quot;,
                                                                                                                                                                                                                                                                                                                                                                                      },
                                                                                                                                                                                                                                                                                                                                                                                              test: {
                                                                                                                                                                                                                                                                                                                                                                                                          required: &quot;测试字段不能为空&quot;,
                                                                                                                                                                                                                                                                                                                                                                                                                      testRule: &quot;该字段的值必须为test&quot;
                                                                                                                                                                                                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                                  
                                                                                                                                                                                                                                                                                                                                                                                                                                  let validation = new Validation(data, rules, messages);" aria-label="复制" data-bs-original-title="复制">
                      <i class="far fa-copy"></i>
          </button>
</div>
      </div><pre class="javascript hljs language-javascript"><span class="hljs-keyword">import</span> <span class="hljs-title class_">Validation</span> <span class="hljs-keyword">from</span> <span class="hljs-string">"@church1117/form-validation"</span>
      
      <span class="hljs-keyword">let</span> data = {
              <span class="hljs-attr">name</span>: <span class="hljs-string">"church"</span>,
                      <span class="hljs-attr">mobile</span>: <span class="hljs-string">"18565919379"</span>,
                              <span class="hljs-attr">age</span>: <span class="hljs-number">19</span>,
                                      <span class="hljs-attr">gender</span>: <span class="hljs-string">'2'</span>,
                                              <span class="hljs-attr">password</span>: <span class="hljs-string">"123456"</span>,
                                                      <span class="hljs-attr">captcha</span>: <span class="hljs-string">"12345"</span>,
                                                              <span class="hljs-attr">idcard</span>: <span class="hljs-string">'42052919910727452X'</span>,
                                                                      <span class="hljs-attr">email</span>: <span class="hljs-string">"xxx@qq.com"</span>,
                                                                              <span class="hljs-attr">test</span>: <span class="hljs-string">"ttt"</span>,
                                                                                      <span class="hljs-attr">birthday</span>: <span class="hljs-string">'1993/11/17'</span>,
                                                                                          }
                                                                                          
                                                                                          <span class="hljs-keyword">let</span> rules = {
                                                                                                  <span class="hljs-attr">name</span>: <span class="hljs-string">"required|between:6,255"</span>,
                                                                                                          <span class="hljs-attr">mobile</span>: <span class="hljs-string">"required|telephone"</span>,
                                                                                                                  <span class="hljs-attr">age</span>: <span class="hljs-string">"numeric|between:8,60"</span>,
                                                                                                                          <span class="hljs-attr">gender</span>: <span class="hljs-string">"numeric|range:"</span> + gender.<span class="hljs-title function_">join</span>(<span class="hljs-string">','</span>),
                                                                                                                                  <span class="hljs-attr">password</span>: <span class="hljs-string">"required|min:6|password"</span>,
                                                                                                                                          <span class="hljs-attr">captcha</span>: <span class="hljs-string">"required|length:5"</span>,
                                                                                                                                                  <span class="hljs-attr">idcard</span>: <span class="hljs-string">"required|idcard"</span>,
                                                                                                                                                          <span class="hljs-attr">email</span>: <span class="hljs-string">"email"</span>,
                                                                                                                                                                  <span class="hljs-comment">// test: "required|testRule"</span>
                                                                                                                                                                          <span class="hljs-attr">birthday</span>: <span class="hljs-string">"datetime"</span>
                                                                                                                                                                              }
                                                                                                                                                                              
                                                                                                                                                                              <span class="hljs-keyword">let</span> messages = {
                                                                                                                                                                                      <span class="hljs-attr">name</span>: {
                                                                                                                                                                                                  <span class="hljs-attr">required</span>: <span class="hljs-string">"名字不能为空"</span>,
                                                                                                                                                                                                              <span class="hljs-attr">between</span>: <span class="hljs-string">"名称长度必须在6~255之间"</span>,
                                                                                                                                                                                                                      },
                                                                                                                                                                                                                              <span class="hljs-attr">mobile</span>: <span class="hljs-string">"不正确的手机格式"</span>,
                                                                                                                                                                                                                                      <span class="hljs-attr">age</span>: {
                                                                                                                                                                                                                                                  <span class="hljs-attr">numeric</span>: <span class="hljs-string">"年龄不是一个有效的数值"</span>,
                                                                                                                                                                                                                                                              <span class="hljs-attr">between</span>: <span class="hljs-string">"年龄必须在18-60岁之间"</span>
                                                                                                                                                                                                                                                                      },
                                                                                                                                                                                                                                                                              <span class="hljs-attr">password</span>: {
                                                                                                                                                                                                                                                                                          <span class="hljs-attr">required</span>: <span class="hljs-string">"密码不能为空"</span>,
                                                                                                                                                                                                                                                                                                      <span class="hljs-attr">min</span>: <span class="hljs-string">"密码长度不能小于6"</span>,
                                                                                                                                                                                                                                                                                                                  <span class="hljs-attr">regex</span>: <span class="hljs-string">"密码只能由数字、大小写字母构成"</span>,
                                                                                                                                                                                                                                                                                                                          },
                                                                                                                                                                                                                                                                                                                                  <span class="hljs-attr">captcha</span>: <span class="hljs-string">"验证码不正确"</span>,
                                                                                                                                                                                                                                                                                                                                          <span class="hljs-attr">idcard</span>: {
                                                                                                                                                                                                                                                                                                                                                      <span class="hljs-attr">required</span>: <span class="hljs-string">"身份证不能为空"</span>,
                                                                                                                                                                                                                                                                                                                                                                  <span class="hljs-attr">idcard</span>: <span class="hljs-string">"身份证格式不正确"</span>,
                                                                                                                                                                                                                                                                                                                                                                          },
                                                                                                                                                                                                                                                                                                                                                                                  <span class="hljs-attr">test</span>: {
                                                                                                                                                                                                                                                                                                                                                                                              <span class="hljs-attr">required</span>: <span class="hljs-string">"测试字段不能为空"</span>,
                                                                                                                                                                                                                                                                                                                                                                                                          <span class="hljs-attr">testRule</span>: <span class="hljs-string">"该字段的值必须为test"</span>
                                                                                                                                                                                                                                                                                                                                                                                                                  }
                                                                                                                                                                                                                                                                                                                                                                                                                      }
                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                      <span class="hljs-keyword">let</span> validation = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Validation</span>(data, rules, messages);</pre><ul><li>messages 可以定义不同粒度的错误信息,如果是字符串,那么该字段的所有验证规则都使用该错误信息。如果是对象,就只使用对应规则的错误信息。</li></ul><h3 id="item-0-4">内置规则</h3><ul><li>required</li><li>telephone</li><li>min</li><li>max</li><li>between</li><li>idcard</li><li>range</li><li>password</li><li>numeric</li><li>length</li><li>email</li><li>datetime</li></ul><h3 id="item-0-5">自定义规则</h3><p>匿名函数参数(value, field, ...params)</p><ul><li>value</li><li>field</li><li>...params</li></ul><div class="widget-codetool" style="display: none;">
      <div class="widget-codetool--inner">
                  <button type="button" class="btn btn-dark rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="Validation.register('testRule', function(value, field) {
                      if (typeof value != 'undefined' &amp;&amp; value != 'test') {
                              throw new Error(`${field} must equal test`)
                                  }
                                  });" aria-label="复制" data-bs-original-title="复制">
                      <i class="far fa-copy"></i>
          </button>
</div>
      </div><pre class="javascript hljs language-javascript"><span class="hljs-title class_">Validation</span>.<span class="hljs-title function_">register</span>(<span class="hljs-string">'testRule'</span>, <span class="hljs-keyword">function</span>(<span class="hljs-params">value, field</span>) {
          <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> value != <span class="hljs-string">'undefined'</span> &amp;&amp; value != <span class="hljs-string">'test'</span>) {
                  <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">`<span class="hljs-subst">${field}</span> must equal test`</span>)
                      }
                      });</pre><h3 id="item-0-6">测试</h3><div class="widget-codetool" style="display: none;">
      <div class="widget-codetool--inner">
                  <button type="button" class="btn btn-dark rounded-0 sflex-center copyCode" data-toggle="tooltip" data-placement="top" data-clipboard-text="npm test" aria-label="复制" data-bs-original-title="复制">
                      <i class="far fa-copy"></i>
          </button>
</div>
      </div><pre class="shell hljs language-shell">npm test</pre>