element-ui Form表單驗證

element-ui Form表單驗證規則全解
element的form表單很是好用,自帶了驗證規則,用起來很方便,官網給的案例對於一些普通場景徹底沒問題,不過一些複雜場景的驗證還得本身多看文檔摸索,本身通過數次爬坑
以後,總結了幾種form表單的驗證規則,爲了便於閱讀,驗證規則是拆分的,完整的代碼放在文末
 
1. 普通輸入驗證
複製代碼
<el-form-item label="活動名稱" prop="name">
    <!-- validate-event屬性的做用是: 輸入時不觸發表單驗證.提交時再驗證,你也能夠設置成動態驗證 -->
    <el-input v-model="registData.name" :validate-event="false"></el-input>
  </el-form-item>

  rules: { // 表單驗證規則
    name: [
      { required: true, message: '請輸入活動名稱' }, // 'blur'是鼠標失去焦點的時候會觸發驗證
      { min: 3, max: 5, message: '長度在 3 到 5 個字符' }
    ]
  }
複製代碼

 

2. 數字類型驗證
 
複製代碼
<el-form-item label="區域面積" prop="area">
    <!-- 輸入的類型爲Number時,須要加一個數字轉換的修飾符,輸入框默認的類型是String類型,可是我試了一下,發現並不能作驗證,因此本身寫了函數方法驗證 -->
    <!-- <el-input v-model.number="registData.area" autocomplete="off"></el-input> -->
    <!-- keyup是鼠標彈起事件, autocomplete是input自帶的原生屬性,自動補全功能,on爲開啓,off爲關閉 -->
    <el-input v-model="registData.area" @keyup.native="InputNumber('area')" autocomplete="off"></el-input>
  </el-form-item>

  area: [
      // 數字類型 'number', 整數: 'integer', 浮點數: 'float'
      // {type: 'number', message: '請輸入數字類型', trigger: 'blur'},
      // {type: 'integer', message: '請輸入數字類型', trigger: 'change'}, // 'change'是表單的值改變的時候會觸發驗證
      {required: true, message: '請輸入區域面積', trigger: 'blur'}
    ],

    // 本身寫的正則驗證,限制用戶輸入數字之外的字符
    // 過濾輸入的金額
    InputNumber (property) {
      this.registData[property] = this.limitInputPointNumber(this.registData[property])
    },

    // 驗證只能輸入數字
    limitInputNumber (val) {
      if (val) {
        return String(val).replace(/\D/g, '')
      }
      return val
    },

    // 限制只能輸入數字(能夠輸入兩位小數)
    limitInputPointNumber (val) {
      if (val === 0 || val === '0' || val === '') {
        return ''
      } else {
        let value = null
        value = String(val).replace(/[^\d.]/g, '') // 清除「數字」和「.」之外的字符
        value = value.replace(/\.{2,}/g, '.') // 只保留第一個. 清除多餘的
        value = value.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
        value = value.replace(/^(-)*(\d+)\.(\d\d).*$/, '$1$2.$3') // 只能輸入兩個小數
        return Number(value)
      }
    },
複製代碼

 

3.1 嵌套驗證(獨立驗證)
 
這種狀況是一行裏有多個輸入框或選擇的狀況,這裏有兩種方法,第一種是el-form嵌套寫法,驗證是獨立的
 
複製代碼
<el-form-item label="活動時間" required>
    <el-col :span="11">
      <el-form-item prop="date1">
        <el-date-picker type="date" placeholder="選擇日期" v-model="registData.date1" style="width: 100%;"></el-date-picker>
      </el-form-item>
    </el-col>
    <el-col class="line" :span="2">-</el-col>
    <el-col :span="11">
      <el-form-item prop="date2">
        <el-time-picker type="fixed-time" placeholder="選擇時間" v-model="registData.date2" style="width: 100%;"></el-time-picker>
      </el-form-item>
    </el-col>
  </el-form-item>

  date1: [
    { type: 'date', required: true, message: '請選擇日期', trigger: 'change' }
  ],
  date2: [
    { type: 'date', required: true, message: '請選擇時間', trigger: 'change' }
  ],
複製代碼

 

3.2 嵌套驗證(聯動驗證)
 
這種是聯動驗證,適用省級聯動場景,先選國家後觸發城市驗證
 
 
 
 
複製代碼
<!-- region是一個對象,國家和城市是它的屬性 -->
  <el-form-item label="活動區域" prop="region">
    <el-select v-model="registData.region.country" placeholder="請選擇國家">
      <el-option label="國家一" value="USA"></el-option>
      <el-option label="國家二" value="China"></el-option>
    </el-select>
    <el-select v-model="registData.region.city" placeholder="請選擇城市">
      <el-option label="城市一" value="shanghai"></el-option>
      <el-option label="城市二" value="beijing"></el-option>
    </el-select>
  </el-form-item>

  region: [
    {
      type: 'object',
      required: true,
      // 這裏有兩種處理,一種是自定義驗證,拿到值後本身對屬性進行驗證,比較麻煩
      // validator: (rule, value, callback) => {
      //   console.log(55, value)
      //   if (!value.country) {
      //     callback(new Error('請選擇國家'))
      //   } else if (!value.city) {
      //     callback(new Error('請選擇城市'))
      //   } else {
      //     callback()
      //   }
      // },
      trigger: 'change',
      // 官網提供了對象的嵌套驗證,只須要把須要驗證的屬性,放在fields對象裏,就會按順序進行驗證
      fields: {
        country: {required: true, message: '請選擇國家', trigger: 'blur'},
        city: {required: true, message: '請選擇城市', trigger: 'blur'}
      }
    }
  ],
複製代碼

 

4. 圖片上傳驗證(手動觸發部分驗證方法)
 
有時候會須要在表單裏上傳圖片,可是圖片上傳是一個異步過程,屬性值改變後不會去觸發驗證規則
 
 
複製代碼
<el-form-item label="活動圖片" prop="fileUrl">
    <el-upload
      :action="action"
      :on-success="handleSuccess"
      :data="uploadData"
      :limit="20"
      list-type="picture-card"
      :on-preview="handlePreview"
      :on-remove="handleRemove">
      <i class="el-icon-plus"></i>
    </el-upload>
  </el-form-item>

  fileUrl: [
    { required: true, message: '請上傳圖片', trigger: 'change' }
  ],

  // 刪除圖片
  handleRemove (file, fileList) {
    this.registData.fileUrl = ''
    // 文件刪除後也要觸發驗證,validateField是觸發部分驗證的方法,參數是prop設置的值
    this.$refs.registerRef.validateField('fileUrl')
  },

  // 圖片上傳
  handleSuccess (res, file, fileList) {
    // 這裏能夠寫文件上傳成功後的處理,可是必定要記得給fileUrl賦值
    this.registData.fileUrl = 'fileUrl'
    // 文件上傳後不會觸發form表單的驗證,要手動添加驗證
    this.$refs.registerRef.validateField('fileUrl')
  },
複製代碼

 

完整的代碼
 
複製代碼
<template>
  <div>
    <p>shopInfo</p>
    <div class="company" id="company">
      <!-- model是驗證的數據來源 -->
      <el-form :model="registData" :rules="rules" ref="registerRef" label-width="100px" class="demo-ruleForm">
        <el-form-item label="活動名稱" prop="name">
          <!-- validate-event輸入時不觸發表單驗證,提交時再驗證,也能夠設置成動態驗證 -->
          <el-input v-model="registData.name" :validate-event="false"></el-input>
        </el-form-item>
        <el-form-item label="區域面積" prop="area">
          <!-- 輸入的類型爲Number時,須要加一個數字轉換的修飾符,輸入框默認的類型是String類型,可是我試了一下,發現並不能作驗證,因此本身寫了函數方法驗證 -->
          <!-- <el-input v-model.number="registData.area" autocomplete="off"></el-input> -->
          <el-input v-model="registData.area" @keyup.native="InputNumber('area')" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="活動區域" prop="region">
          <el-select v-model="registData.region.country" placeholder="請選擇國家">
            <el-option label="國家一" value="USA"></el-option>
            <el-option label="國家二" value="China"></el-option>
          </el-select>
          <el-select v-model="registData.region.city" placeholder="請選擇城市">
            <el-option label="城市一" value="shanghai"></el-option>
            <el-option label="城市二" value="beijing"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="活動時間" required>
          <el-col :span="11">
            <el-form-item prop="date1">
              <el-date-picker type="date" placeholder="選擇日期" v-model="registData.date1" style="width: 100%;"></el-date-picker>
            </el-form-item>
          </el-col>
          <el-col class="line" :span="2">-</el-col>
          <el-col :span="11">
            <el-form-item prop="date2">
              <el-time-picker type="fixed-time" placeholder="選擇時間" v-model="registData.date2" style="width: 100%;"></el-time-picker>
            </el-form-item>
          </el-col>
        </el-form-item>
        <el-form-item label="即時配送" prop="delivery">
          <el-switch v-model="registData.delivery"></el-switch>
        </el-form-item>
        <el-form-item label="活動性質" prop="type">
          <el-checkbox-group v-model="registData.type">
            <el-checkbox label="美食/餐廳線上活動" name="type"></el-checkbox>
            <el-checkbox label="地推活動" name="type"></el-checkbox>
            <el-checkbox label="線下主題活動" name="type"></el-checkbox>
            <el-checkbox label="單純品牌曝光" name="type"></el-checkbox>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="特殊資源" prop="resource">
          <el-radio-group v-model="registData.resource">
            <el-radio label="線上品牌商贊助"></el-radio>
            <el-radio label="線下場地免費"></el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="活動圖片" prop="fileUrl">
          <el-upload
            :action="action"
            :on-success="handleSuccess"
            :data="uploadData"
            :limit="20"
            list-type="picture-card"
            :on-preview="handlePreview"
            :on-remove="handleRemove">
            <i class="el-icon-plus"></i>
          </el-upload>
        </el-form-item>
        <el-form-item label="活動形式" prop="desc">
          <el-input type="textarea" v-model="registData.desc"></el-input>
        </el-form-item>
        <el-form-item>
          <!-- 提交的時候傳入的是表單的ref -->
          <el-button type="primary" @click="submitForm('registerRef')">當即建立</el-button>
          <el-button @click="resetForm('registerRef')">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>
<style scoped>
  .company {
    padding: 30px;
    text-align: left;
    width: 600px;
  }
</style>
<script>
export default {
  name: 'shopInfo',

  data () {
    return {
      registData: {
        name: '', // 名稱
        area: '', // 面積
        region: {}, // 地區
        date1: '', // 日期
        date2: '', // 時間
        delivery: false, // 即時配送
        type: [], // 活動性質
        resource: '', // 特殊資源
        fileUrl: '', // 活動圖片
        desc: '' // 活動形式
      }, // 須要驗證的表單屬性,必須在data中定義
      rules: { // 表單驗證規則
        name: [
          { required: true, message: '請輸入活動名稱' }, // 'blur'是鼠標失去焦點的時候會觸發驗證
          { min: 3, max: 5, message: '長度在 3 到 5 個字符' }
        ],
        area: [
          // 數字類型
          // {type: 'number', message: '請輸入數字類型', trigger: 'blur'},
          // {type: 'integer', message: '請輸入數字類型', trigger: 'change'}, // 'change'是表單的值改變的時候會觸發驗證
          {required: true, message: '請輸入區域面積', trigger: 'blur'}
        ],
        region: [
          {
            type: 'object',
            required: true,
            // validator: (rule, value, callback) => {
            //   console.log(55, value)
            //   if (!value.country) {
            //     callback(new Error('請選擇國家'))
            //   } else if (!value.city) {
            //     callback(new Error('請選擇城市'))
            //   } else {
            //     callback()
            //   }
            // },
            trigger: 'change',
            fields: {
              country: {required: true, message: '請選擇國家', trigger: 'blur'},
              city: {required: true, message: '請選擇城市', trigger: 'blur'}
            }
          }
        ],
        date1: [
          { type: 'date', required: true, message: '請選擇日期', trigger: 'change' }
        ],
        date2: [
          { type: 'date', required: true, message: '請選擇時間', trigger: 'change' }
        ],
        type: [
          { type: 'array', required: true, message: '請至少選擇一個活動性質', trigger: 'change' }
        ],
        resource: [
          { required: true, message: '請選擇活動資源', trigger: 'change' }
        ],
        fileUrl: [
          { required: true, message: '請上傳圖片', trigger: 'change' }
        ],
        desc: [
          { required: true, message: '請填寫活動形式', trigger: 'blur' }
        ]
      },
      action: `https://jsonplaceholder.typicode.com/posts/`,
      uploadData: {userId: 1304, pathName: 'company'}
    }
  },

  created () {

  },

  methods: {
    // 過濾輸入的金額
    InputNumber (property) {
      this.registData[property] = this.limitInputPointNumber(this.registData[property])
    },

    // 驗證只能輸入數字
    limitInputNumber (val) {
      if (val) {
        return String(val).replace(/\D/g, '')
      }
      return val
    },

    // 限制只能輸入數字(能夠輸入兩位小數)
    limitInputPointNumber (val) {
      if (val === 0 || val === '0' || val === '') {
        return ''
      } else {
        let value = null
        value = String(val).replace(/[^\d.]/g, '') // 清除「數字」和「.」之外的字符
        value = value.replace(/\.{2,}/g, '.') // 只保留第一個. 清除多餘的
        value = value.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
        value = value.replace(/^(-)*(\d+)\.(\d\d).*$/, '$1$2.$3') // 只能輸入兩個小數
        return Number(value)
      }
    },

    // 預覽圖片
    handlePreview (file) {

    },

    // 刪除圖片
    handleRemove (file, fileList) {
      this.registData.fileUrl = ''
      // 文件刪除後也要觸發驗證,validateField是觸發部分驗證的方法,參數是prop設置的值
      this.$refs.registerRef.validateField('fileUrl')
    },

    // 圖片上傳
    handleSuccess (res, file, fileList) {
      // 這裏能夠寫文件上傳成功後的處理,可是必定要記得給fileUrl賦值
      this.registData.fileUrl = 'fileUrl'
      // 文件上傳後不會觸發form表單的驗證,要手動添加驗證
      this.$refs.registerRef.validateField('fileUrl')
    },

    submitForm (formName) {
      console.log(this.registData)
      this.$refs[formName].validate((valid) => {
        if (valid) {
          alert('submit!')
        } else {
          console.log('error submit!!')
          return false
        }
      })
    },

    resetForm (formName) {
      this.$refs[formName].resetFields()
    }
  }
}
複製代碼

 

再補充兩個錯誤顯示的方法
有時候咱們的數據在修改頁面中,賦值爲空會觸發驗證錯誤,這種在一個prop控制多個form-item時會出現.這時候但願頁面加載時不驗證,在特定時候驗證,可使用error這個屬性
error初始值爲空時不會展現錯誤信息,一旦有值就會在頁面展現錯誤信息
複製代碼
<el-form-item class="region" label="" :error="nameError">
  <el-input v-model="registData.name" @change="changeName" :validate-event="false"></el-input>
</el-form-item>

methods: {
  data: {
    return () {
      nameError: ''
    }
  }
  changeName () {
    // 設置了單獨的error時,不會觸發el-form的驗證,它只根據error是否有值來展現錯誤
    if (this.registData.name) {
      this.nameError = ''
    } else {
      this.nameError = '請輸入名稱'
    }
  }
}
複製代碼
另外一種場景: 自定義錯誤樣式
el-form的錯誤信息默認是在輸入框底部一行展現,若是須要特意的樣式,可使用slot
複製代碼
<el-form-item label="" prop="password">
    <el-input v-model="perfectInfo.password" :placeholder="pwdPlaceholder" :maxlength="24" auto-complete="new-password" >
    </el-input>
    <template slot="error" slot-scope="slot">
      <div class="el-form_tip tt">
        <div class="item_tip">{{pwdFormatTips1}}</div>
        <div class="item_tip">{{pwdFormatTips2}}</div>
        <div class="item_tip">{{pwdFormatTips3}}</div>
        <div class="item_tip">{{pwdFormatTips4}}</div>
      </div>
    </template>
  </el-form-item>
複製代碼
相關文章
相關標籤/搜索