vue 表單校驗(二)


vue 表單校驗(二)

vue element-ui表單校驗

由於現在使用element-ui進行form表單校驗,因而使用其自帶的校驗規則進行校驗,發現有些並不是那么好校驗,或者說是校驗起來很繁瑣,因而一直在研究中

表單校驗分類

前后端校驗

  • 前端校驗
  • 后端校驗
    這種目前一般是結合起來使用,很少單純前端校驗,或者單純后端校驗的

前端檢驗

  • 數據錄入時校驗
  • 數據回顯時校驗
  • 動態創建時校驗
  • 數據是否必填時校驗

接下來所談論的校驗都是基於前端進行校驗,若是后天校驗,只是統一校驗規則而已,這樣前后便可以統一了。其實這里並不是很簡單,但是不得不細心,而已最好,前后台都要其校驗規則,以及校驗話術放在一個公共的地方,避免在每個具體文件內進行修改。若是能更好的話,類似 google email 那樣,通過后台返回規則類型,以及對應前台的具體編號,進行顯示即可(比如1: 不能為空, 2:校驗規則不合...) 這樣的好處,前台只認這個數字即可,不然后台返回什么,前台出什么錯誤,都是統一顯示(這個扯遠了),講今天的重點

基於 element-ui 自帶的 表單校驗

  • 數據錄入時校驗

element-ui form validate

  • el-form 標簽
    • 屬性
      • model 對象卻只能是一維 { a: 1, b: 2 }, 不能是 { a: { b: 2 } }, 不然關聯不到
      • rules 按照規則要求即可
      • ref 提交表單時觸發
  • el-form-item 標簽 必須使用這個進行包裹 表單框... 校驗才會有效
    • 屬性
      • prop 只有標識了這個才會進入校驗
<template>
  <el-form
    :model="ruleForm"
    ref="ruleForm"
    label-width="100px"
    :rules="rules">
    <el-form-item
      label="活動名稱"
      prop="name">
      <el-input v-model="ruleForm.name"></el-input>
    </el-form-item>
    <el-form-item>
      <el-button
        type="primary"
        @click="submitForm('ruleForm')">立即創建</el-button>
      <el-button @click="resetForm('ruleForm')">重置</el-button>
    </el-form-item>
  </el-form>  
</template>

<script>
  ...
  data () {
    const isNum = (rule, value, callback) => { // 參數順序必須如
      let reg = /^[0-9]{5,20}$/;
      if (reg.test(value)) {
        callback()
      } else {
        callback(new Error("不是數據"))
      }
    }

    return {
      ruleForm: {
        name: ''
      },
      rules: {
        name: [
          {
            required: true,      // 用來設置是否必填
            message: '不能為空',  // 錯誤信息展示
            trigger: 'blur'      // 觸發校驗事件
          },
          {
            min: 3,  
            max: 5,
            message: '長度在 3 到 5 個字符',
            trigger: 'blur'
          },
          {
            validator: isNum,    // 自定義校驗
            trigger: ['blur', 'change']  // 填寫 blur change時,可以達到類似 input事件,實時進行校驗
          }
        ]
      }
    }
  },
  methods: {
    /**
     * 表單提交
     */
    submitFomr (formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          alert('success')
        } else {
          alert('error')
        }
      })
    },
    /** 
     * 重置表單
     */
    resetForm (formName) {
      this.$refs[formName].resetFields()
    }
  }
</script>

以上是一個正常表單的大致模型

  • 數據回顯時校驗

主要是數據返回時,要不要觸發校驗

  • 不觸發 github 這里有一些解釋,不是很好弄
  • 觸發 (跟產品溝通過,傾向於這種)
    當前基於數據反顯時就觸發校驗
setFormData () {
 setTimeout(() => {
   this.ruleForm = {
     name: '測試項目',
     region: 2,
     type: [1, 2],
     resource: 1,
     desc: '測試數據回顯時校驗顏色變化問題'
   }

   this.$nextTick(() => {
     // 為了回顯時,不只是el-select 校驗被觸發
     this.$refs.ruleForm.validate()
   })
 }, 1500)
  • 動態創建時校驗

有時候需要動態創建一個輸入框時,也需要檢驗,這時候就需要動態校驗,不然一直卡着過不去

<el-row
  class="sc-row"
  :gutter="20"
  v-for="(t, i) in ruleForm.contactList"
  :key="t.id">
  <!-- :key="i" 沒問題; :key="t.id" 時,不會變亮  ==== 沒必要在第一次賦值時給id,新增時再給即可-->
  <el-col :span="8">
    <el-form-item
      label="姓氏"
      :prop="'contactList.' + i +'.family_name'"
      :rules="[
            { required: true, message: '不能為空', trigger: ['blur', 'change']}
          ]">
      <el-input v-model="t.family_name"></el-input>
    </el-form-item>
  </el-col>
  <el-col :span="8">
    <el-form-item
      label="名字"
      :prop="'contactList.' + i +'.contact_name'"
      :rules="[
            {required: true, message: '不能為空', trigger: ['blur', 'change']}
          ]">
      <el-input v-model="t.contact_name"></el-input>
    </el-form-item>
  </el-col>
  <el-col :span="8">
    <el-button @click.prevent="deleteConcats(t)">刪除</el-button>
  </el-col>
</el-row>

重點,切記切記

  • 循環 v-for == v-for = '(item, i) in list' :key="item.id" i

  • el-form-item 屬性

    • :prop = "contactList.${i}.contact_name "
    • :rules="[{{required: true, message: '不能為空', trigger: ['blur', 'change']}]" 寫相應的校驗規則
  • 刪除已添加的表單

    • v-for 綁定時,:key="item.id" 使用對應值的id,而不是對應的索引i
    addConcats () {
      this.ruleForm.contactList.push({
        family_name: '',
        contact_name: '',
        id: Date.now() //  還是需要使用,這樣可以 避免校驗觸發時,刪除后卻沒有變化
      })
    },
    deleteConcats (item) {
        const List = this.ruleForm.contactList
        const index = List.findIndex((val) => {
          return item === val
        })
        List.splice(index, 1)
      }
    }
    
  • 數據是否必填時校驗

<el-form-item
  label="是不是必填"
  prop="isRequire"
  :rules="[
    {required: isRequire, message: '請填寫', trigger: 'blur'}
  ]">
  <el-input v-model="ruleForm.isRequire"></el-input>
</el-form-item>

是否選填,個人建議直接以動態form表單形式進行展示,這樣便可以通過 { reuired: isRequire }isRequire Boolean類型

總結

至此,大致的form表單校驗就差不多了,雖然看起來很簡單,但是也是我不斷采坑過來的,在此,我更加推薦使用 element-ui-verify,里面有詳細的文檔,多多關注即可

  • 當前校驗的缺點
    • 動態創建
    <el-row class="sc-row" :gutter="20" v-for="(t, i) in ruleForm.contactList" :key="t.id">
      <el-col :span="8">
        <el-form-item
          label="姓氏"
          :prop="'contactList.' + i +'.family_name'"
          :rules="[
            { required: true, message: '不能為空', trigger: ['blur', 'change']}
          ]">
          <el-input v-model="t.family_name"></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-form-item
          label="名字"
          :prop="'contactList.' + i +'.contact_name'"
          :rules="[
            {required: true, message: '不能為空', trigger: ['blur', 'change']}
          ]">
          <el-input v-model="t.contact_name"></el-input>
        </el-form-item>
      </el-col>
      <el-col :span="8">
        <el-button @click.prevent="deleteConcats(t)">刪除</el-button>
      </el-col>
    </el-row>
    

    上面的 姓氏和名字 同為中文或英文時,很難進行判斷 element密碼兩次是否相同,但是當前動態創建時,無法傳遞索引,自定義方法中無法進行傳參,導致拿不到同一索引下的姓氏跟名字,也就無法進行匹配判斷了

  • 其他注意細節
    • 在自定義驗證里面每一個判斷都要有callback(),就是要保證callback()一定會執行到,不然既不報錯,也不提交代碼,令人很是無語
    • async-validator
    • 上面例子的code

到此,算是一個給自己年末去心病吧,這個困惑我太久了,到現在想想都恐怖,算是簡單補充下吧,后期再多多注意

在此拋出幾個問題,留給自己思考

  • 大型表單時,哪兒錯誤,自動定位到哪兒,同時 focus
  • 統一錯誤信息,后台傳給前台具體id,以供前台進行錯誤信息展示,這個前台統一管理
  • 考慮使用其他校驗插件,多多擴充自己的腦容量


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM