使用HTML和Vuejs进行表单验证

他们说大多数网络应用只是HTML表单。好吧,表单需要验证,谢天谢地,HTML5带有许多优秀的内置表单验证功能,可用于电子邮件,数字,最大值,分钟等。您甚至可以使用模式编写自己的验证规则。在本文中,我将讨论如何在覆盖无聊的默认值时利用HTML5验证,以便您可以根据需要显示验证错误。我将与Vuejs合作,但即使你不使用Vue,你也可以随时跟进。

让我们从Bootstrap示例的Checkout表单的开始,这样我们就不必过于担心样式了。您可以在此处克隆器。设置应如下所示:

使用Vuejs Starter进行HTML验证

默认的HTML5验证不会立即显示所有表单错误。具有讽刺意味的是,一旦用户提交,浏览器实际上就知道所有无效字段,所以现在我们所要做的就是检查它们然后显示我们喜欢的内容。

现在让我们为表单和一个使用Vuejs捕获提交事件的监听器添加一个id。

<form class="needs-validation" id="validated-form">
  <div class="row">
    <div class="col-md-6 mb-3">
      <label for="firstName">First name</label>
      <input type="text" class="form-control" id="firstName" placeholder="" value="" required>
      <div class="invalid-feedback">
        Valid first name is required.
      </div>
    </div>
    <div class="col-md-6 mb-3">
      <label for="lastName">Last name</label>
      <input type="text" class="form-control" id="lastName" placeholder="" value="" required>
      <div class="invalid-feedback">
        Valid last name is required.
      </div>
    </div>
  </div>
  <!-- Rest of the form removed to save space   -->
  <button class="btn btn-primary btn-lg btn-block" type="submit" @click.prevent="submitForm()">SUBMIT</button>
</form>

添加事件监听器以提交表单

然后在我们的form-validation.js文件中,我们将初始化Vuejs并创建处理表单提交和验证的方法。

const vueApp = new Vue({
    el: '#validated-form',
    methods: {
        submitForm () {
            if (this.validateForm()) {
                console.log('formValidated');
                //submit form to backend
            }
        },
        validateForm () {
            var formId = 'validated-form';
            var nodes = document.querySelectorAll(`#${formId} :invalid`);
            console.log(nodes);
            return true;
        }
    }
});

这里我们创建了两个方法submitFormvalidateForm。submitForm调用validateForm,如果满足所有验证规则,则返回true。现在,我们从控制日志记录中查看所有无效的表单输入,我们可以找到许多有趣的属性,包括我们可以向用户显示的validationMessage

输入属性无效

接下来,让我们创建将保存每个无效输入的validationErrors的数据属性。然后我们将循环遍历无效输入数组以设置每个输入。

const vueApp = new Vue({
    el: '#validated-form',
    data: function () {
        return {
            validationErrors: {
                firstName: null,
                lastName: null,
                username: null,
                email: null,
                address: null,
                country: null,
                state: null,
                zip: null,
            }
        }
    },
    methods: {
        submitForm () {
            if (this.validateForm()) {
                alert('Form Submitted')
                //submit form to backend
            }
        },
        validateForm () {
            var formId = 'validated-form';
            var nodes = document.querySelectorAll(`#${formId} :invalid`);
            var errorObjectName = 'validationErrors';
            var vm = this; //current vue instance;

            Object.keys(this[errorObjectName]).forEach(key => {
                this[errorObjectName][key] = null
            });

            if (nodes.length > 0) {
                nodes.forEach(node => {
                    this[errorObjectName][node.name] = node.validationMessage;
                    node.addEventListener('change', function (e) {
                        vm.validateForm();
                    });
                });

                return false;
            }
            else {
                return true;
            }
        }
    }
});

在这里,我们做了很多事情。我们创建了validationErrors数据属性来保存每个字段的错误消息。validationErrors对象的每个属性对应于要验证的每个表单元素的name属性。因此在validateForm方法中,我们清除任何先前的错误消息,然后遍历无效字段以设置其相应的validationErrors。我们还添加了一个事件侦听器,一旦无效字段发生更改,就会重新验证。

现在我们需要为要验证的每个字段添加名称属性,这在制作表单时非常正常。然后,我们还应该添加将向用户显示错误消息的span元素。

<form class="needs-validation" id="validated-form">
    <div class="row">
        <div class="col-md-6 mb-3">
            <label for="firstName">First name</label>
            <input type="text" class="form-control" name="firstName" placeholder="" value="" required>
            <span class="text-danger" v-if="validationErrors.firstName" v-text="validationErrors.firstName"></span>
        </div>
        <div class="col-md-6 mb-3">
            <label for="lastName">Last name</label>
            <input type="text" class="form-control" name="lastName" placeholder="" value="" required>
            <span class="text-danger" v-if="validationErrors.lastName" v-text="validationErrors.lastName"></span>
        </div>
    </div>

    <div class="mb-3">
        <label for="username">Username</label>
        <div class="input-group">
            <div class="input-group-prepend">
                <span class="input-group-text">@</span>
            </div>
            <input type="text" class="form-control" name="username" placeholder="Username" required>
            <span class="text-danger" v-if="validationErrors.username" style="width: 100%;" v-text="validationErrors.username"></span>
        </div>
    </div>

    <div class="mb-3">
        <label for="email">Email <span class="text-muted">(Optional)</span></label>
        <input type="email" class="form-control" name="email" placeholder="you@example.com">
        <div class="text-danger" v-if="validationErrors.email" style="width: 100%;">
            <span v-text="validationErrors.email"></span>
        </div>
    </div>
    
    <!--  Rest of form hidden for space    -->

    <button class="btn btn-primary btn-lg btn-block" type="submit"
        @click.prevent="submitForm()">SUBMIT</button>
</form>

现在,一旦我们提交表单,我们的用户就可以看到他们需要修复的所有验证错误。很酷的是我们已经完成了它而无需引入额外的库来进行验证。现在,因为我们正在利用Vue的数据绑定能力,我们可以从这里获得有关我们希望如何显示错误的创意。


使用HTML5模式

如果我们需要超出可用的验证规则,该怎么办?例如,检查邮政编码是否有效。这就是HTML5模式非常有用的地方,因为我们可以在HTML中编写正则表达式来执行我们需要的任何类型的检查。我觉得有人正在宣誓正常表达,但幸运的是你可以在html5pattern.com找到一大堆有用的正则表达式。

好吧,找到一个正则表达式比我想象的要困难一些。事实证明,他们大多是7位数字。所以[0-9] {13,16}应该可以正常工作。现在我们遇到了一个新问题。关于HTML5模式的错误消息不是很有用,所以我们需要指定自己的。我们需要一种方法来告诉validateForm函数显示什么消息。

<form class="needs-validation" id="validated-form">
    <div class="row">
        <!--  Rest of form hidden for space    -->
        
        <div class="col-md-3 mb-3">
            <label for="zip">Zip</label>
            <input type="text" class="form-control" name="zip" placeholder="" pattern="[0-9]{7}" title="Invalid Zip Code" required>
            <span class="text-danger" v-if="validationErrors.zip" style="width: 100%;" v-text="validationErrors.zip"></span>
        </div>
    </div>

    <button class="btn btn-primary btn-lg btn-block" type="submit"
        @click.prevent="submitForm()">SUBMIT</button>
</form>

添加标题和模式属性

然后我们可以在validateForm方法中检查title属性:

validateForm (formId = 'validated-form', errorObjectName = 'validationErrors') {
    var nodes = document.querySelectorAll(`#${formId} :invalid`);
    var vm = this; //current vue instance;

    Object.keys(this[errorObjectName]).forEach(key => {
        this[errorObjectName][key] = null
    });

    if (nodes.length > 0) {
        nodes.forEach(node => {
            if (node.title) {
                this[errorObjectName][node.name] = node.title;
            }
            else {
                this[errorObjectName][node.name] = node.validationMessage;
            }

            node.addEventListener('change', function (e) {
                vm.validateForm(formId, errorObjectName);
            });
        });

        return false;
    }
    else {
        return true;
    }
}

这里我们添加了一个if-else块来检查title属性,如果找不到则只显示默认错误消息。此外,formIderrorObjectName变量现在被传递到validateForm函数,这允许我们在同一个网页上验证我们选择的方式和方式。


我们已经能够为表单验证创建一个简单的约定配置方法。一旦我们在validationErrors对象中指定了表单字段的名称属性,我们的cool validateForm函数就会利用内置的HTML5功能来完成剩下的工作,我们需要做的就是按照我们想要的方式显示错误。一如既往,我希望这有助于某人。

如果您正在使用Vue,则可以使用此代码段快速启动验证,并且它也不应该很难应用于其他前端框架。您还可以 此repo演示网站上找到本文的工作代码。

干杯!

转:https://itnext.io/form-validation-with-html-vuejs-54ec18e473aa

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,492评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,048评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,927评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,293评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,309评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,024评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,638评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,546评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,073评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,188评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,321评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,998评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,678评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,186评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,303评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,663评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,330评论 2 358

推荐阅读更多精彩内容

  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,328评论 0 9
  • 1### Menu 第14章 表单脚本 14.1 表单的基础知识 14.1.1 提交表单 14.1.2 重置表单 ...
    ft207741阅读 414评论 0 2
  • 1、简介 Laravel 提供了多种方法来验证应用输入数据。默认情况下,Laravel 的控制器基类使用Valid...
    伊Summer阅读 1,526评论 0 3
  • 版本:Angular 5.0.0-alpha 表单是商业应用的支柱,我们用它来执行登录、求助、下单、预订机票、安排...
    soojade阅读 1,281评论 0 1
  • HTML 5 HTML5概述 因特网上的信息是以网页的形式展示给用户的,因此网页是网络信息传递的载体。网页文件是用...
    阿啊阿吖丁阅读 3,904评论 0 0