如何在Vue中使用表单验证

来自菜鸟教程
跳转至:导航、​搜索

介绍

几乎每个 Web 应用程序都以某种方式使用表单,因为这样的开发人员总是必须处理表单验证。 如果您是新开发人员,可能很难决定如何最好地解决这个问题。 根据您使用的堆栈,有许多选项可供选择。

在本教程中,我们将学习如何使用 Vue 在表单中实现表单验证。

我们希望在用户点击提交按钮后立即显示错误消息——无需向服务器发送响应——因为验证是在客户端进行的。 拥有客户端验证并不会消除在服务器上验证请求的需要——这也非常重要。

构建第一个示例

有了这些,让我们构建我们的表单。 首先,我们的 App 组件只会渲染 Register 组件:

<div id="app">
  <div>
    <Register />
  </div>
</div>

脚本部分将如下所示:

new Vue({
  el: "#app"
})

对于 Register 组件,我们希望显示一个带有输入字段的表单:

  <div>
    <h2>Register</h2>

    <form @submit.prevent="register" method="post">
      <div>
        <label>Name:</label>
        <input type="text" v-model="user.name" />
        <div>{{ errors.name }}</div>
      </div>
      <div>
        <label>Phone:</label>
        <input type="text" v-model="user.phone" />
        <div>{{ errors.phone }}</div>
      </div>
      <div>
        <label>Email:</label>
        <input type="text" v-model="user.email" />
        <div>{{ errors.email }}</div>
      </div>
      <div>
        <label>Password:</label>
        <input type="password" v-model="user.password" />
        <div>{{ errors.password }}</div>
      </div>
      <div>
        <button type="submit">Submit</button>
      </div>
    </form>
  </div>

.prevent 方法用于在提交时停止表单的默认行为。 该表单有四个输入字段,分别是姓名、电子邮件、电话和密码。 所有这些都需要自己的验证。 如果任何输入有错误,它将显示在输入字段下方。

由于每个字段都是唯一的,我们需要确保验证适合匹配它们的唯一性。 一般的一个是所有字段都不应该为空。 我们可以使用 !field.length 来检查这一点,其中 field 将等同于我们拥有的任何输入字段。 为了保持我们的代码干净,验证器将在 Vue 实例之外定义。 如果您在使用 Vue CLI 搭建的应用程序中构建它,这意味着您将在单独的文件中拥有验证器。

const validateName = name => {
  if (!name.length) {
    return { valid: false, error: "This field is required" };
  }
  return { valid: true, error: null };
};

const validatePhone = phone => {
  if (!phone.length) {
    return { valid: false, error: 'This field is required.' };
  }

  if (!phone.match(/^[+][(]?[0-9]{1,3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,7}$/gm)) {
    return { valid: false, error: 'Please, enter a valid international phone number.' };
  }

  return { valid: true, error: null };
}

const validateEmail = email => {
  if (!email.length) {
    return { valid: false, error: "This field is required" };
  }
  if (!email.match(/^\w+([.-]?\w+)_@\w+(_[_.-]?\w+)_(.\w{2,3})+$/)) {
    return { valid: false, error: "Please, enter a valid email." };
  }
  return { valid: true, error: null };
};

const validatePassword = password => {
  if (!password.length) {
    return { valid: false, error: "This field is required" };
  }
  if (password.length < 7) {
    return { valid: false, error: "Password is too short" };
  }
  return { valid: true, error: null };
};

对于电子邮件和电话号码等独特字段,我们使用正则表达式来确保它与特定模式匹配。 每个验证器都是一个函数,它将接收输入字段作为参数。 从上面可以看出,每个函数都返回 validerror。 这就是我们将用来确定是否应该提交表单的方法。 要查看实际情况,Register 组件的外观如下:

Vue.component('register', {
  template: '#register',
  data() {
    return {
      user: {
        email: '',
        password: '',
        name: '',
        phone: ''
      },
      valid: true,
      success: false,
      errors: {},
      message: null
    }
  },
  methods: {

    register() {
      this.errors = {}

      const validName = validateName(this.user.name);
      this.errors.name = validName.error;
      if (this.valid) {
        this.valid = validName.valid
      }

      const validPhone = validatePhone(this.user.phone);
      this.errors.phone = validPhone.error;
      if (this.valid) {
        this.valid = validPhone.valid
      }

      const validEmail = validateEmail(this.user.email);
      this.errors.email = validEmail.error;
      if (this.valid) {
        this.valid = validEmail.valid
      }

      const validPassword = validatePassword(this.user.password)
      this.errors.password = validPassword.error
      if (this.valid) {
        this.valid = validPassword.valid
      }

      if (this.valid) {
        alert('HURRAAYYY!! :-)\n\n' + JSON.stringify(this.user))
      }
    }
  }
})

如果验证器对任何字段返回错误,则返回的错误将保存在 errors.fieldName 中——其中 fieldName 是输入字段的名称,然后显示给用户查看出错。

当所有字段返回 validtrue 时,我们可以继续提交表单。 对于本教程,我们将显示一个警告框。

使用 Joi

Joi 允许您为 JavaScript 对象构建模式,这些模式可用于验证输入。 它经常在使用 Express 和 Restify 时使用。 我们可以通过为我们的 Register 组件定义一个模式来在本教程中使用它。

这是架构:

import Joi from "joi";

const phoneRegex = /^[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,7}$/gm;
const phone = Joi.string().regex(phoneRegex)
  .options({
    language: {
      string: {
        regex: {
          base: 'must be a valid phone number'
        }
      }
    }
  });

const userValidation = {};
userValidation.create = {
  first_name: Joi.string().min(2).max(24).required(),
  email: Joi.string().email().required(),
  password: Joi.string().min(7).required(),
  phone: phone.required()
};

然后,我们可以使用 Register 组件中的模式来验证用户的输入:

Vue.component('register', {
  template: '#register',
  data() {
    return {
      user: {
        name: '',
        email: '',
        password: '',
        phone: ''
      },
      valid: false,
      success: false,
      errors: {},
      issues: {}
    }
  },
  methods: {
    // method that validates the user input using the schema
    validate(value, schema) {
      const result = Joi.validate(value, schema, { abortEarly: false });
      if (result.error) {
        result.error.details.forEach((error) => {
          this.issues[error.path[0]] = error.message;
        });
        return false;
      }
      return true;
    },

    register() {
      // validation method is called and passed the inputs and schema
      this.validate(this.user, userValidation.create);
        if (Object.keys(this.issues).length > 0) {
          this.errors = this.issues;
          return false;
        }
        alert('HURRAAYYY!! :-)\n\n' + JSON.stringify(this.user))
    }
  }
})

我们声明了一个 validate 方法,它将接受用户输入和我们定义的模式。 如果在验证后发现错误,我们将返回 false 和遇到的错误。 如果没有错误,我们会像以前一样显示警告框。

结论

VeeValidate 和 Vuelidate 是您在 Vue 应用程序中处理表单验证时也可以使用的替代方案。