<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          在 Vue 中實(shí)現(xiàn)拖放式圖片上傳組件

          共 11426字,需瀏覽 23分鐘

           ·

          2021-03-14 13:28

          上篇教程中,學(xué)院君給大家演示了如何基于 Laravel + Vue 框架快速實(shí)現(xiàn)圖片上傳并且給文章添加了封面圖片功能。除了傳統(tǒng)的點(diǎn)擊按鈕選擇圖片上傳之外,我們還可以基于 HTML5 原生提供的文件拖放 API 讓文件上傳變得更簡(jiǎn)單一些,接下來,我們就來演示如何在 Vue 框架中實(shí)現(xiàn)一個(gè)圖片拖放上傳組件。

          后端接口和表單外圍功能都是現(xiàn)成的,只需要在 resources/js/components/form 目錄下編寫一個(gè)獨(dú)立的 DragImage 子組件,然后在 PostForm 中引入它即可。

          模板代碼

          首先,我們?cè)?DragImage.vue 中編寫 HTML 模板代碼如下:

          <template>
              <div class="form-group">
                  <div class="dropbox">
                      <input class="drag-file" type="file" ref="image" :name="name" :disabled="isSaving" @change="fileChange" accept="image/*">
                      <p v-if="isInitial">
                          拖放圖片開始上傳<br>或者點(diǎn)擊選擇圖片上傳
                      </p>
                      <p v-if="isSaving">
                          圖片上傳中...
                      </p>
                  </div>
                  <div v-if="isSuccess">
                      <div class="alert alert-success" role="alert">
                          圖片上傳成功!<a href="javascript:void(0)" @click="reset()">重新上傳</a>
                      </div>
                  </div>
                  <div v-if="isFailed">
                      <div class="alert alert-danger" role="alert">
                          圖片上傳失敗!<a href="javascript:void(0)" @click="reset()">重新上傳</a>
                      </div>
                  </div>
                  <InputText type="hidden" :name="field" v-model="filePath"></InputText>
                  <img :src="filePath" class="img-responsive img-thumbnail" style="width: 50%;" v-if="filePath">
              </div>
          </template>

          我們通過 div[class=dropbox] 這個(gè)容器定義拖放上傳區(qū)域,并且通過 accept 屬性設(shè)置只支持圖片上傳,如果已經(jīng)有圖片在上傳,則該組件處于禁用狀態(tài),在空閑狀態(tài)下,將圖片文件拖放到該區(qū)域會(huì)觸發(fā) fileChange 事件發(fā)送圖片上傳請(qǐng)求。在圖片拖放區(qū)域,會(huì)根據(jù)不同的狀態(tài)顯示不同的文案(這些狀態(tài)和方法我們馬上會(huì)提供)。

          然后是圖片上傳成功或失敗的消息提示,并且提供了重新上傳鏈接清空已上傳的圖片。

          最后和上篇教程實(shí)現(xiàn)的文件上傳組件一樣,是隱藏的圖片路徑字段和圖片預(yù)覽功能,如果圖片上傳成功,或者父級(jí)作用域已經(jīng)包含封面圖片,就會(huì)在圖片預(yù)覽區(qū)域渲染出來。

          腳本代碼

          為了讓上面的模板代碼可以正常渲染和工作,需要在 Vue 組件中編寫腳本代碼:

          <script>
          import InputText from './InputText';

          const STATUS_INITIAL = 0, STATUS_SAVING = 1, STATUS_SUCCESS = 2, STATUS_FAILED = 3;

          export default {
              props: ['name''field''path'],
              components: {InputText},
              data() {
                  return {
                      currentStatusnull,
                      filePaththis.path
                  }
              },
              computed: {
                  isInitial() {
                      return this.currentStatus === STATUS_INITIAL;
                  },
                  isSaving() {
                      return this.currentStatus === STATUS_SAVING;
                  },
                  isSuccess() {
                      return this.currentStatus === STATUS_SUCCESS;
                  },
                  isFailed() {
                      return this.currentStatus === STATUS_FAILED;
                  }
              },
              mounted() {
                  this.reset();
              },
              methods: {
                  reset() {
                      // 重置狀態(tài)字段值
                      this.currentStatus = STATUS_INITIAL;
                      this.$emit('clear');  //  清理父級(jí)作用域報(bào)錯(cuò)信息
                  },
                  fileChange() {
                      // 上傳文件后才會(huì)執(zhí)行后續(xù)步驟
                      if (this.$refs.image.files.length === 0) {
                          return;
                      }

                      // 清理父級(jí)作用域錯(cuò)誤信息
                      this.$emit('clear');

                      // 填充表單數(shù)據(jù)
                      const formData = new FormData();
                      formData.append(this.name, this.$refs.image.files[0]);

                      // 開始上傳
                      this.currentStatus = STATUS_SAVING;
                      axios.post('/image/upload', formData, {
                          headers: {
                              'Content-Type''multipart/form-data'
                          }
                      }).then(resp => {
                          this.currentStatus = STATUS_SUCCESS;
                          this.filePath = resp.data.path;
                          this.$emit('success'this.field, this.filePath);
                      }).catch(error => {
                          this.currentStatus = STATUS_FAILED;
                          let errors = {};
                          errors[this.field] = error.response.data.errors[this.name];
                          this.$emit('error', errors);
                      });
                  }
              }
          }
          </script>

          除了新增一個(gè)狀態(tài)字段 currentStatus 和對(duì)應(yīng)的維護(hù)邏輯,以及與之相關(guān)的計(jì)算屬性定義外,其他邏輯和上篇教程創(chuàng)建的文件上傳組件都差不多,就不多做介紹了。

          樣式代碼

          現(xiàn)在我們的拖放式圖片上傳組件基本功能就已經(jīng)編寫好了,我們?cè)倬帉懭缦聵邮酱a讓其看起來更美觀一些:

          <style scoped>
          .dropbox {
              outline2px dashed grey;
              outline-offset: -10px;
              background: lightcyan;
              color: dimgray;
              padding10px 10px;
              min-height200px;
              position: relative;
              cursor: pointer;
          }

          .drag-file {
              opacity0;
              width100%;
              height200px;
              position: absolute;
              cursor: pointer;
          }

          .dropbox:hover {
              background: lightblue;
          }

          .dropbox p {
              font-size1.2em;
              text-align: center;
              padding50px 0;
          }

          .alert {
              margin-top10px;
          }
          </style>

          在文章表單中引入

          最后我們需要在文章發(fā)布/編輯表單中引入 DragImage 組件讓其生效:

          <div class="form-group">
              <Label name="title" label="封面圖片"></Label>
              <!--
              <InputFile name="image" field="image_path" :path="form.image_path"
                         @clear="clear('image_path')" @success="uploadSuccess" @error="uploadError">
              </InputFile>
              -->

              <DragImage name="image" field="image_path" :path="form.image_path"
                         @clear="clear('image_path')" @success="uploadSuccess" @error="uploadError">

              </DragImage>
              <ErrorMsg :error="form.errors.get('image_path')"></ErrorMsg>
          </div>

          ...

          <script>
          import DragImage from "./form/DragImage";

          export default {

              components: {DragImage, FormSection, InputText, InputFile, TextArea, Label, ErrorMsg, Button, ToastMsg},

              ...
          }
          </script>

          這個(gè)時(shí)候,再打開文章發(fā)布/編輯頁(yè)面,就可以看到如下的封面圖片上傳 UI 了:


          需要注意的是,除了拖放上傳之外,DragImage 組件也支持傳統(tǒng)的點(diǎn)擊->選擇圖片->上傳流程,不同于之前的點(diǎn)擊按鈕,現(xiàn)在點(diǎn)擊拖放區(qū)域就可以了。

          演示圖片拖放式上傳

          我們可以簡(jiǎn)單演示下圖片拖放式上傳:

          你可以將右側(cè)本地文件系統(tǒng)中的任意圖片拖到左側(cè)瀏覽器封面圖片對(duì)應(yīng)的上傳區(qū)域,完成圖片拖放上傳。

          你還可以在此基礎(chǔ)上讓 DragImage 組件支持上傳多張圖片,感興趣的同學(xué)可以自行去研究下如何實(shí)現(xiàn)。

          本系列教程首發(fā)在Laravel學(xué)院(laravelacademy.org),你可以點(diǎn)擊頁(yè)面左下角閱讀原文鏈接查看最新更新的教程。

          瀏覽 80
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  麻豆精品无码久久久介绍 | 国产一级黄片视频 | 欧美性爱亚洲 | 日日AⅤ| 日韩一级黄片 |