欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

UniApp表單校驗(yàn)兩種方式對比詳解

 更新時(shí)間:2025年03月24日 11:30:39   作者:碼農(nóng)研究僧  
本文對比了UniApp中表單校驗(yàn)的命令式和聲明式兩種方式,通過實(shí)戰(zhàn)示例展示了它們的優(yōu)缺點(diǎn),并有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下

以下主要針對Demo講解,從實(shí)戰(zhàn)中的體會

何為命令式 何為聲明式

  • 命令式的體驗(yàn),隨時(shí)都會有提交的按鈕,但是點(diǎn)擊提交才會顯示不滿足的條件!

  • 聲明式的體驗(yàn),不滿足條件時(shí),按鈕框是灰色的!

  1. 命令式:
    提交邏輯復(fù)雜,需要異步校驗(yàn)(如服務(wù)端唯一性檢查)
    表單字段多,依賴用戶行為觸發(fā)驗(yàn)證
    需要復(fù)用校驗(yàn)函數(shù),或表單邏輯分散多處

  2. 聲明式:
    表單簡單明了
    用戶體驗(yàn)優(yōu)先,提前告知無法提交的情況
    狀態(tài)可視化,一目了然

對比項(xiàng)命令式校驗(yàn)(方法中校驗(yàn))聲明式校驗(yàn)(computed + disabled 控制)
方式在 submit() 方法內(nèi)通過 validateForm() 顯式校驗(yàn)通過 computed 計(jì)算屬性實(shí)時(shí)判斷是否可提交
編程范式命令式(Imperative)聲明式(Declarative)
表達(dá)方式手動控制流程:如果失敗就 return false自動計(jì)算狀態(tài):按鈕根據(jù)是否滿足條件自動禁用
可復(fù)用性校驗(yàn)邏輯聚焦在 validateForm(),但要手動調(diào)用校驗(yàn)邏輯綁定在狀態(tài)中,按鈕等 UI 自動響應(yīng)
用戶體驗(yàn)用戶點(diǎn)擊“提交”后才提示不通過一目了然,提交按鈕禁用,無法誤觸提交
靈活性可以靈活插入額外邏輯,如提交前彈窗確認(rèn)邏輯適合純狀態(tài)驅(qū)動,復(fù)雜流程需另外處理
適用場景需要流程控制、嵌套邏輯、異步校驗(yàn)時(shí)更適合表單項(xiàng)簡單明確、狀態(tài)驅(qū)動時(shí)更適合

1. 實(shí)戰(zhàn)

實(shí)戰(zhàn)中抽取的Demo比較簡易:

命令式 submit 校驗(yàn)方式(validateForm)

<template>
  <button type="primary" @click="submit">提交</button>
</template>

<script>
export default {
  data() {
    return {
      imgCntrF: [],
      damPhotoList: []
    };
  },
  methods: {
    validateForm() {
      if (!this.imgCntrF.length) {
        uni.showToast({ title: '請拍攝箱門照片', icon: 'none' });
        return false;
      }
      if (this.damPhotoList.length < 2) {
        uni.showToast({ title: '請至少拍攝 2 張照片', icon: 'none' });
        return false;
      }
      return true;
    },
    async submit() {
      if (!this.validateForm()) return;
      // 執(zhí)行提交邏輯
      console.log("提交成功");
    }
  }
}
</script>

聲明式 computed 控制按鈕狀態(tài)

<template>
  <button type="primary" :disabled="!canSubmit" @click="submit">提交</button>
</template>

<script>
export default {
  data() {
    return {
      photoList: {
        door: '',  // 對應(yīng) imgCntrF
        side: ''
      },
      damPhotoList: [],
      photoField: [
        { key: 'door', label: '箱門照片' },
        { key: 'side', label: '側(cè)面照片' }
      ]
    };
  },
  computed: {
    canSubmit() {
      return this.photoField.every(field => this.photoList[field.key]) &&
             this.damPhotoList.length >= 2;
    }
  },
  methods: {
    submit() {
      console.log("提交成功");
    }
  }
}
</script>

2. Demo

以UniApp( Vue2 語法 + script 寫法)

命令式校驗(yàn)提交(Imperative)

<template>
  <view class="container">
    <view class="section">
      <text>箱門照片:</text>
      <button @click="selectBoxDoorPhoto">選擇照片</button>
      <image v-if="imgCntrF" :src="imgCntrF" class="img-preview" />
    </view>

    <view class="section">
      <text>破損照片:</text>
      <button @click="addDamPhoto">添加照片</button>
      <view class="photo-list">
        <image v-for="(photo, index) in damPhotoList" :key="index" :src="photo" class="img-preview" />
      </view>
    </view>

    <button type="primary" @click="submit">提交</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      imgCntrF: '', // 箱門照片 URL
      damPhotoList: [] // 破損照片 URL 列表
    };
  },
  methods: {
    selectBoxDoorPhoto() {
      uni.chooseImage({
        count: 1,
        success: (res) => {
          this.imgCntrF = res.tempFilePaths[0];
        }
      });
    },
    addDamPhoto() {
      uni.chooseImage({
        count: 1,
        success: (res) => {
          this.damPhotoList.push(res.tempFilePaths[0]);
        }
      });
    },
    validateForm() {
      if (!this.imgCntrF) {
        uni.showToast({ title: '請拍攝箱門照片', icon: 'none' });
        return false;
      }
      if (this.damPhotoList.length < 2) {
        uni.showToast({ title: '請至少拍攝 2 張破損照片', icon: 'none' });
        return false;
      }
      return true;
    },
    submit() {
      if (!this.validateForm()) return;

      // 模擬提交成功
      uni.showToast({ title: '提交成功', icon: 'success' });
    }
  }
};
</script>

<style>
.container {
  padding: 20rpx;
}
.section {
  margin-bottom: 30rpx;
}
.img-preview {
  width: 200rpx;
  height: 200rpx;
  margin-top: 10rpx;
}
.photo-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10rpx;
}
</style>

聲明式按鈕控制提交(Declarative)

<template>
  <view class="container">
    <view class="section">
      <text>箱門照片:</text>
      <button @click="selectBoxDoorPhoto">選擇照片</button>
      <image v-if="photoList.door" :src="photoList.door" class="img-preview" />
    </view>

    <view class="section">
      <text>破損照片:</text>
      <button @click="addDamPhoto">添加照片</button>
      <view class="photo-list">
        <image v-for="(photo, index) in damPhotoList" :key="index" :src="photo" class="img-preview" />
      </view>
    </view>

    <button type="primary" :disabled="!canSubmit" @click="submit">提交</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      photoList: {
        door: '' // 箱門照片
      },
      damPhotoList: []
    };
  },
  computed: {
    canSubmit() {
      return !!this.photoList.door && this.damPhotoList.length >= 2;
    }
  },
  methods: {
    selectBoxDoorPhoto() {
      uni.chooseImage({
        count: 1,
        success: (res) => {
          this.photoList.door = res.tempFilePaths[0];
        }
      });
    },
    addDamPhoto() {
      uni.chooseImage({
        count: 1,
        success: (res) => {
          this.damPhotoList.push(res.tempFilePaths[0]);
        }
      });
    },
    submit() {
      uni.showToast({ title: '提交成功', icon: 'success' });
    }
  }
};
</script>

<style>
.container {
  padding: 20rpx;
}
.section {
  margin-bottom: 30rpx;
}
.img-preview {
  width: 200rpx;
  height: 200rpx;
  margin-top: 10rpx;
}
.photo-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10rpx;
}
</style>

到此這篇關(guān)于UniApp表單校驗(yàn)兩種方式對比詳解的文章就介紹到這了,更多相關(guān)UniApp表單校驗(yàn)方式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論