<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      使用 Ant-Design-Vue 制作一個帶圖片上傳功能的表單對話框

      功能需求

      使用 AntdvModal 組件內(nèi)嵌一個 a-form 表單,具有添加數(shù)據(jù)和圖片的功能。

      頁面結(jié)構(gòu)設(shè)計

      <template>
        <!--Modal-->
        <a-modal>
          <div>
            <a-form>
              <a-form-item label="水果名稱" name="fruitName">
                <a-input type="text" placeholder="水果名稱">
              </a-form-item>
              <a-form-item label="價 格" name="price">
                <a-input type="number" placeholder="價格(元/公斤)">
              </a-form-item>
              <a-form-item label="庫 存" name="stock">
                <a-input type="number" placeholder="庫存(公斤)">
              </a-form-item>
              <a-form-item label="圖 片">
                <a-upload>
                  <div>
                    <img v-if="!base64img" src="@/assets/plus.png">
                    <!-- ↑ 如果沒有添加圖片則顯示一個加號占位符圖片 -->
                    <img v-else :src="base64img">
                    <!-- ↑ 如果添加了圖片則顯示圖片 -->
                  </div>
                </a-upload>
              </a-form-item>
              <a-form-item>
                <a-button>提交</a-button>
              </a-form-item>
            </a-form>
          </div>
        </a-modal>
      </template>
      

      只展示了基礎(chǔ)的頁面結(jié)構(gòu),省略了綁定的事件、邏輯和樣式代碼。

      思路整理

      Modal 中有一個表單,表單中有 4 個子項目,前三個為 input 輸入框,最后一個是圖片上傳的組件,均為必填項。所以要為前三個輸入框加上前端的表單驗證,只需要在 a-form:rules 中加入 [{required: true, message: ...}]。上傳圖片則采用單獨的邏輯判斷,因為表單輸入的前三項和圖片上傳采用的是不同的接口,上傳表單數(shù)據(jù)(水果名稱、價格、庫存)和圖片的路徑使用的是一個接口,上傳圖片至服務(wù)器使用的是另一個接口。所以我們要在點擊提交按鈕時添加一個判斷圖片是否為空的操作,如果為空則拒絕向服務(wù)器發(fā)送請求。

      關(guān)于圖片上傳的部分可以看 這篇文章

      由于 AntdvModal 組件是有默認(rèn)的 確認(rèn)取消 按鈕,這點對于提交表來來說不太方便,所以要禁用默認(rèn)的按鈕,再向表單中添加一個 form-item 提交按鈕。

      在上傳文件時,為了避免上傳相同名稱的文件,我們要用當(dāng)前時間戳來為文件重命名,手段是 const renameFile = new File(...)

      添加數(shù)據(jù)成功后,需要重新從數(shù)據(jù)庫中獲取下數(shù)據(jù),這個方法直接使用 onMounted 中的就可以了。由于數(shù)據(jù)量較少,故沒有在服務(wù)端使用分頁,每次請求都會返回數(shù)據(jù)庫中的所有數(shù)據(jù)。

      邏輯部分

      // ↓ 控制 Modal 組件是否顯示
      const addModalVisible = ref<boolean>(false);
      
      // 點擊顯示 Modal 的回調(diào)
      function showAddModal() {
        console.log("Show Add Modal");
        addModalVisible.value = true;
      }
      
      // 表單數(shù)據(jù)
      const formData = reactive({
        fruitName: "",
        price: "",
        stock: "",
        avatar: "",
      })
      
      /**
       * 上傳圖片需要用到的變量
       */
      const fileList = ref();
      // ↑ 放置圖片的
      const base64img = ref();
      // ↑ 用來放置 base64 轉(zhuǎn)碼后的圖片
      const btnLoading = ref<boolean>(false);
      // 控制 提交 按鈕的 loading 狀態(tài)
      
      
      /**
       * 上傳文件的回調(diào)
       */
      function beforeUpload(file: any) {
        const isImg = (file.type === 'image/jpeg' || file.type === 'image/png');
        // 如果文件不是圖片格式則禁止上傳
        if (!isImg) {
          Notice.error("只能上傳 jpeg/jpg/png 格式的文件!");
          // ↑ Notice.error 是我自己寫的 Notice 類的一個靜態(tài)函數(shù)
          // 用的是 antdv 的 Notifiacation
          return Upload.LIST_IGNORE;
          // ↑ 這個不解釋了,上一篇博客中提到了
        }
      
        fileList.value = file;
        // ↓ 獲取所需要上傳圖片的 Base64 編碼
        getBase64(fileList.value, (cb_img: string) => {
          // 將獲取到的所要上傳圖片的 Base64 編碼渲染到圖片上
          base64img.value = cb_img;
        })
        return false;
      }
      
      /**
       * 待上傳圖片被刪除的回調(diào)
       */
      function handleRemove() {
        fileList.value = null;
        // ↑ 置空待上傳文件列表
        base64img.value = null;
        // ↑ 顯示默認(rèn)占位圖
      }
      
      /**
       * 點擊 Modal 中的添加按鈕的回調(diào)
       */
      function addItem() {
        // 添加圖片文件到服務(wù)器指定位置
        const imgForm = new FormData();
        if (fileList.value != null) {
          // ↓ 以當(dāng)前時間戳重命名文件
          const newFileName = Date.now() + "." + fileList.value.name.substring(fileList.value.name.lastIndexOf(".") + 1);
          // ↓ avatar 是數(shù)據(jù)庫中儲存圖片地址的字段,后面會加上地址重新賦值一次
          formData.avatar = newFileName;
          const renameFile = new File([fileList.value], newFileName);
          // ↑ 創(chuàng)建新文件:以新文件名重命名文件
          imgForm.append("file", renameFile);
        } else {
          Notice.error("圖片不能為空!");
          return Upload.LIST_IGNORE;
        }
        btnLoading.value = true;
      
        // 將圖片上傳至服務(wù)器
        const addData = new Promise((resolve, reject) => {
          // fruitApi 是自己封裝的 Axios
          fruitApi({
            method: 'put',
            url: 'api/upload',
            data: imgForm,
          })
              .then((resp) => {
                resolve(resp);
              })
              .catch((error) => {
                reject(error);
              })
        })
      
        // 添加數(shù)據(jù)至數(shù)據(jù)庫
        // 并添加文件的名稱和路徑至數(shù)據(jù)庫
        const uploadPic = new Promise((resolve, reject) => {
          fruitApi({
            method: 'post',
            url: 'api/fruits',
            data: {
              fruitName: formData.fruitName,
              avatar: imagesAddr + "/" + formData.avatar,
              // imagesAddr 是服務(wù)器儲存圖片的地址
              price: formData.price,
              stock: formData.stock,
            }
          })
              .then((resp: any) => {
                resolve(resp);
              })
              .catch((error) => {
                reject(error);
              })
        })
      
        Promise.all([addData, uploadPic])
            .then((resp) => {
              console.log("請求成功: ");
              console.log(resp);
              changeUploadItemColor("success");
              // ↑ 上傳成功改變顏色,也在上個博客提到過了
              Notice.success("添加成功!");
      
              setTimeout(() => {
                getFruits();
                // ↑ 上傳成功后重新獲取數(shù)據(jù)
              }, 500)
      
            })
            .catch((error) => {
              console.log("請求失敗: ");
              console.log(error);
              changeUploadItemColor("error");
              Notice.error("添加失敗~");
            })
            .finally(() => {
              btnLoading.value = false;
              // 取消按鈕的 loading 狀態(tài)
            })
      }
      

      完善頁面結(jié)構(gòu)

      <!--Modal-->
      <a-modal v-model:visible="addModalVisible"
               title="模態(tài)對話框"
               :confirm-loading="btnLoading"
               :footer="null"
      >
        <div>
          <a-form
              :model="formData"
              @finish="addItem"
          >
            <a-form-item label="水果名稱" name="fruitName" :rules="[{required: true, message: '請輸入水果名稱'}]">
              <a-input type="text" placeholder="水果名稱" v-model:value="formData.fruitName"/>
            </a-form-item>
            <a-form-item label="價 格" name="price" :rules="[{required: true, message: '請輸入價格'}]">
              <a-input type="number" placeholder="價格(元/公斤)" suffix="RMB" v-model:value="formData.price"/>
            </a-form-item>
            <a-form-item label="庫 存" name="stock" :rules="[{required: true, message: '請輸入庫存'}]">
              <a-input type="number" placeholder="庫存(公斤)" v-model:value="formData.stock"/>
            </a-form-item>
            <a-form-item label="圖 片">
              <a-upload
                  :before-upload="beforeUpload"
                  :max-count="1"
                  @remove="handleRemove"
              >
                <div>
                  <img v-if="!base64img" src="@/assets/plus.png" />
                  <img v-else :src="base64img" />
                </div>
              </a-upload>
            </a-form-item>
      
            <a-form-item>
              <a-button html-type="submit" :loading="btnLoading">提交</a-button>
            </a-form-item>
          </a-form>
        </div>
      </a-modal>
      

      完整代碼:https://blog-static.cnblogs.com/files/blogs/754613/modalForm.vue.js?t=1665405534

      posted @ 2022-10-10 20:40  HuStoking  閱讀(673)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产AV大陆精品一区二区三区| 精品人妻无码一区二区三区性| 国产精品视频午夜福利| 性欧美乱熟妇xxxx白浆| 免费无码AV一区二区波多野结衣| 亚洲色www永久网站| 国产在线精品中文字幕| 99精品国产一区二区三区| 久久无码高潮喷水| 国产情侣激情在线对白| 亚洲顶级裸体av片| 久久久一本精品99久久精品36| 清新县| 日本一区二区久久人妻高清| 国产激情艳情在线看视频| 亚洲男人第一无码av网| 国产一区二区三区美女| 亚洲精品一区二区三区综合 | 国产精品久久久久久久久人妻| 少妇伦子伦精品无吗| 久久老熟女一区二区蜜臀| 精品人妻人人做人人爽夜夜爽| 久久99精品久久久久久| 亚洲第一区二区国产精品| 国产成人午夜在线视频极速观看| 亚洲日韩性欧美中文字幕| 亚洲一区三区三区成人久| AV老司机AV天堂| 亚洲男人第一无码av网站| 国产午夜视频在线观看| 欧洲熟妇色xxxxx欧美| 熟女一区二区中文字幕| 精品午夜福利无人区乱码| 在线看免费无码的av天堂| 欧美人与zoxxxx另类| 高清一区二区三区不卡视频| 日本中文字幕乱码免费| 久久天天躁狠狠躁夜夜avapp | 大冶市| 一二三三免费观看视频| 日本高清日本在线免费|