vue3中的表單校驗(yàn)

一、普通校驗(yàn)

綁定ref:ref="editRef"

<el-form label-position="top" :model="value" ref="editRef">
    <el-form-item class="detail__modify">
      <el-input v-model="out.outType"></el-input
    >
</el-form-item>
</el-form>
...

提交時校驗(yàn):editRef.value.validate()

 const editRef = ref();
editRef.value.validate().then(async function () {
               
                try {
                    await fetchDetail({...param})
                } 
  ...

如果需要取消校驗(yàn),比如取消表單編輯的時候,就需要重置表單校驗(yàn),否則可能會有校驗(yàn)信息提示。此時使用 editRef.value.resetFields();

        function cancel(): void {
            editRef.value.resetFields();
            handleClear();
            ctx.emit('close');
        }

二、循環(huán)表單項(xiàng)的校驗(yàn)

請求到的數(shù)據(jù)在表單里循環(huán)展示,每條數(shù)據(jù)都需要一個表單項(xiàng)進(jìn)行展示,對每個循環(huán)出來的表單項(xiàng)分別進(jìn)行校驗(yàn)。

循環(huán)的數(shù)據(jù)為value.outStations, props中outStations是循環(huán)的數(shù)組,index是循環(huán)的index,后邊拼接的是需要校驗(yàn)對象的字段名也即 v-model="out.type" 中綁定的字段名。

<div v-for="(out, index) in value.outStations" :key="index">
    <div class="platform">
        <el-form-item
            label="Off-app platforms"
            :prop="`outStations.${index}.type`"
            :rules="
                [COOPERATION.BR_TeleKwai_Partner_BR, COOPERATION.IN_Family__Group].includes(
                    Number(value.agreementId)
                )
                    ? []
                    : [{ required: true, message: 'Required', trigger: 'blur' }]
            "
        >
            <el-input v-model="out.outType"></el-input>
        </el-form-item>
            ...
      <el-form-item>..</el-form-item>
           ....
    </div>
</div>
                          

rules是校驗(yàn),可以為每個form-item單獨(dú)設(shè)置(如上代碼),也可以在setup中設(shè)置(如下述所示)。校驗(yàn)方式都是一樣的。

在setup中設(shè)置rules:

  1. 校驗(yàn)規(guī)則為靜態(tài)校驗(yàn)

script:

    const dataRules = reactive({
            outType: [{ required: true, message: 'Required', trigger: 'blur' }],
        });

template:

   <el-form-item
    :prop="`outStations.${index}.type`"
    :rules="dataRules.outType"
></el-form-item>
  1. 校驗(yàn)規(guī)則根據(jù)條件動態(tài)校驗(yàn)

比如根據(jù)循環(huán)出的值判斷是否校驗(yàn),可以使用函數(shù)返回校驗(yàn)規(guī)則:

script:

// 傳入當(dāng)前校驗(yàn)的字段(type)以及判斷條件(id )      
const funcRules = function (type: string, id: any): any {
            if (type === 'outType' || type === 'fansCont') {
                return [
                    COOPERATION.BR_TeleKwai_Partner_BR,
                    COOPERATION.IN_Family__Group,
                ].includes(Number(id))
                    ? []
                    : [{ required: true, message: 'Required', trigger: 'blur' }];
            }
        };

template:

   <el-form-item
        :prop="`outStations.${index}.type`"
        :rules="funcRules('outType', value.agreementId)"
    >
        > <el-input v-model="out.outType"></el-input
    ></el-form-item>
<el-form-item
        :prop="`outStations.${index}.fansCont`"
        :rules="funcRules('fansCont', value.agreementId)"
    >
        > <el-input v-model="out.fansCount"></el-input
    ></el-form-item>

三、循環(huán)表單項(xiàng)添加了異步校驗(yàn)函數(shù),全部校驗(yàn)通過才能提交

循環(huán)表單項(xiàng)里,如果給每個form-item 添加其他異步的校驗(yàn)方法,提交之前需要判斷所填數(shù)據(jù)是否滿足條件,才能提交,可使用Promise.all 方法。

template:

 <ks-form-item
    :prop="`outStations.${index}.userId`"
    rules="
            [{ required: true, message: 'Required', trigger: 'change' }]
    "
>
    <ks-input
        v-model="out.userId"
        placeholder="ID"
        @input="checkVerify(out)"
    ></ks-input>
</ks-form-item>

checkVerify異步校驗(yàn)失敗則捕獲異常,返回false作為判斷值。

這里使用了 @input方法,一開始想到的使用@change方法,但是校驗(yàn)結(jié)果blur之后才能觸發(fā),后又改用@keyup方法,但是復(fù)制過去的值不會觸發(fā)校驗(yàn)。最后才想到用 @input方法 ,可以輸入實(shí)時校驗(yàn)。

Script:

   async function checkVerify(info: any): Promise<any> {
      try {
          await fetchOutstation(info);
      } catch (e) {
          message.error(e);
          return false; 
      }
  }
  
  ...
  // 對提交的對象數(shù)組的每一項(xiàng)都執(zhí)行一次異步校驗(yàn)函數(shù),得到一個執(zhí)行結(jié)果為promise的數(shù)組
  const promiseAllArr = addForm.agreementOutInfos.map((info: any) => {
                    return checkVerify(info);
                });
// 使用Promise.all 得到函數(shù)執(zhí)行結(jié)果
                const result = await Promise.all(promiseAllArr);
                const invalid = result.some((d: any) => d === false);// 如果都校驗(yàn)通過,result數(shù)組里沒有false 值

這里每個form 如果:model 綁定的數(shù)據(jù)是相同的,但是校驗(yàn)的ref值不能相同,ref是獲取dom節(jié)點(diǎn),對每個form 需要唯一綁定。 表單項(xiàng)要么寫在一個form 里,要么分成幾個form之后綁定不同的ref。

    Promise.all([editRef1.value, editRef2.value, editRef3.value].map(item => item.validate())).then(async function () { ... }

四、循環(huán)表單中單個表單的獨(dú)立校驗(yàn)

根據(jù)請求到的數(shù)據(jù)循環(huán)創(chuàng)建表單,每個表單都應(yīng)該是獨(dú)立的,校驗(yàn)規(guī)則也是獨(dú)立的。

前面提到的表單普通校驗(yàn)中,通過定義 const editRef = ref(); 給表單form綁定ref="editRef"得到整個表單的校驗(yàn)對象以及校驗(yàn)相關(guān)的方法。 如果表單是循環(huán)出來的,則該ref也應(yīng)該是動態(tài)綁定的。

重新定義editRef ,使用數(shù)組保存每個表單的指向,數(shù)組項(xiàng)應(yīng)該為Ref類型,可掛載dom節(jié)點(diǎn)相關(guān)的方法。

 const editRef = ref<Array<Ref>>([]);
...
// 請求到數(shù)據(jù)賦值給ruleForm.agreementInfos之后,遍歷該對象為 editRef 賦值:
ruleForm.agreementInfos.forEach((item: any, index: number) => {
                editRef.value.push(ref(`editRef${index}`)); // editRef[0] = ref(`editRef0`)
            });

循環(huán)表單template,每個form綁定ref為:ref="editRef[idx]"

  <div
      v-for="(value, idx) in ruleForm.agreementInfos"
      :key="value.agreementId"
  >
      <ks-form label-position="top" :model="value" :ref="editRef[idx]"> 
          <ks-form-item>
             <ks-input v-model="value.memberName"></ks-input
    >
          </ks-form-item>
      </ks-form>
  <div>

提交時找到當(dāng)前表單,該表單獨(dú)立校驗(yàn)通過之后才能將表單數(shù)據(jù)提交到服務(wù)器。關(guān)鍵點(diǎn): editRef.value[idx].value.validate()
script:

        async function SubmitAgreementInfo(agreementId: any): Promise<any> {
            let idx = -1;
            const currentData: any = ruleForm.agreementInfos?.forEach((item: any, index: number) => {
                if (item.agreementId === agreementId) {
                    idx = index;
                }
            });
            editRef.value[idx].value.validate().then(async function () {
                await fetchSubmit({ param });
            });
        }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容