为啥这个 Vue 3 表单验证脚本会失败?

Posted

技术标签:

【中文标题】为啥这个 Vue 3 表单验证脚本会失败?【英文标题】:Why does this Vue 3 form validation script fail?为什么这个 Vue 3 表单验证脚本会失败? 【发布时间】:2022-01-05 09:37:45 【问题描述】:

我正在使用 Vue 3 开发 Users CRUD 应用程序。我在尝试验证“添加新用户”表单中的数据时遇到了麻烦。

更准确地说,我使用下面的函数来确保没有表单字段是空的

isNotEmpty() 
  return (
    this.formData.first_name &&
    this.formData.last_name &&
    this.formData.email
  );

由于我无法弄清楚的原因,formErrors 数组看起来像这样 ["The email is invalid"] 而不是 ["There are empty filelds","The email is invalid"];

const usersApp = 
  data() 
    return 
      users: [
          id: 1,
          first_name: "John",
          last_name: "Doe",
          email: "john.doe@gmail.com"
        ,
        
          id: 2,
          first_name: "Jane",
          last_name: "Doe",
          email: "jane.doe@gmail.com"
        
      ],
      formData: 
        first_name: "",
        last_name: "",
        email: ""
      ,
      formErrors: [],
      userAdded: false
    ;
  ,
  methods: 
    isNotEmpty() 
      return (
        this.formData.first_name &&
        this.formData.last_name &&
        this.formData.email
      );
    ,
    isEmail(email) 
      return String(email)
        .toLowerCase()
        .match(
          /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]1,3\.[0-9]1,3\.[0-9]1,3\.[0-9]1,3\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]2,))$/
        );
    ,
    formValidation() 
      this.formErrors = [];

      if (!this.isNotEmpty) 
        this.formErrors.push("There are empty filelds");
      

      if (!this.isEmail(this.formData.email)) 
        this.formErrors.push("The email is invalid");
      

      console.log(this.formErrors);
    ,
    resetAddFormData() 
      this.formData.first_name = "";
      this.formData.last_name = "";
      this.formData.email = "";
      this.userAdded = false;
    ,
    addUser() 
      // Validate form data
      this.formValidation();

      // Make New User
      let newUser = 
        first_name: this.formData.first_name,
        last_name: this.formData.last_name,
        email: this.formData.email
      ;

      // Add new user
      if (this.formErrors.length == 0) 
        this.users.push(newUser);
        this.userAdded = true;
        window.setTimeout(this.resetAddFormData, 1000);
      
    
  ,
  watch: 
    users() 
      this.users();
    
  
;

Vue.createApp(usersApp).mount("#app");
.logo 
  width: 30px;


.nav-item 
  width: 100%;


@media (min-width: 768px) 
  .nav-item 
    width: auto;
  


.users-table-item-active 
  transition: opacity 2s ease;
  opacity: 0;


.users-table-item 
  opacity: 1;


.alert 
  padding: 0.6rem 0.75rem;
  text-align: center;
  font-weight: 600;
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script src="https://unpkg.com/vue@next"></script>



<div id="app">
  <nav class="navbar navbar-expand-sm bg-dark navbar-dark">
    <!-- Brand -->
    <a class="navbar-brand p-0" href="#">
      <img src="https://www.pngrepo.com/png/303293/180/bootstrap-4-logo.png"  class="logo">
    </a>

    <!-- Links -->
    <div class="navbar-nav w-100">
      <ul class="navbar-nav ml-auto" id="navbarSupportedContent">
        <li class="nav-item">
          <button type="button" class="btn btn-sm btn-success" data-toggle="modal" data-target="#exampleModalCenter">
            Add user
          </button>
        </li>
      </ul>
    </div>
  </nav>

  <div class="container">

    <div class="card my-2">
      <h5 class="card-header px-2">Users</h5>
      <div class="card-body p-0">
        <table class="table table-striped m-0">
          <thead>
            <tr>
              <th>Firstname</th>
              <th>Lastname</th>
              <th>Email</th>
            </tr>
          </thead>
          <tbody name="users-table" is="transition-group">
            <tr v-for="user, key in users" :key="user.id">
              <td>user.first_name</td>
              <td>user.last_name</td>
              <td>user.email</td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>

  <div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h3 class="modal-title h6" id="exampleModalLongTitle">Add New User</h3>
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
        </div>
        <div class="modal-body">
          <div v-if="this.formErrors.length > 0">
            <div v-for="error in formErrors" class="alert alert-danger">
              error
            </div>
          </div>
          <div v-if="userAdded" class="alert alert-success">User added successfully!</div>
          <form @submit.prevent="addUser" novalidate>
            <div class="form-group mb-2">
              <input type="text" class="form-control input-sm" placeholder="First name" v-model="formData.first_name">
            </div>
            <div class="form-group mb-2">
              <input type="text" class="form-control input-sm" placeholder="Last name" v-model="formData.last_name">
            </div>
            <div class="form-group mb-2">
              <input type="email" class="form-control input-sm" placeholder="Email address" v-model="formData.email">
            </div>
            <div class=" mt-2">
              <button type="submit" class="btn btn-sm btn-block btn-success">Submit</button>
            </div>
          </form>
        </div>
      </div>
    </div>
  </div>

</div>
我做错了什么?

【问题讨论】:

【参考方案1】:

您似乎忘记实际调用 isNotEmpty 函数。现在代码正在检查变量 isNotEmpty 是否已定义,并反转语句。

if (!this.isNotEmpty) 
    this.formErrors.push("There are empty filelds");
  

应该是

if (!this.isNotEmpty()) 
    this.formErrors.push("There are empty filelds");
  

【讨论】:

【参考方案2】:

您可以在每个字段中使用规则,而不是使用计算布尔值来检查您的表单是否有效,如下所示:

定义规则

data 中定义规则,例如:

rules: 
    notNull: v => 
      if(!v) return 'The field cannot be null'
      else return true
    ,

为您的输入添加规则

<v-text-field
   v-model='myModel'
   type='number'
   label='MyLbael'
   :rules='[rules.notNull]'
/>

检查您的表单是否有效

检查您的表单在this.$refs.myForm.validate() 条件下是否有效(通过指定表单的引用)

【讨论】:

以上是关于为啥这个 Vue 3 表单验证脚本会失败?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 和 Vue 身份验证表单在登录失败时重新加载

uView UI 表单校验 相关字段有数据有值的情况下非空验证失败问题

vue element ui表单验证不通过,滚动到页面上第一个验证失败的输入框位置

vue 使用element表单不触发验证

vue前端页面表单显隐后校验错位的问题

Vue+Ant Design表单验证