vue項目 攜帶參數進行文件和文件夾上傳

介紹:由於element的el-upload不支持文件夾上傳,所以用了vue-simple-uploader,實現了文件夾/文件的攜帶form data 和 headers參數上傳。vue-simple-uploader還能用於切分上傳、斷續上傳,此處項目沒有用到。

想對上傳做更多的處理的小夥伴,推薦去看源碼。

另:以下代碼加了文件列表的拖拽。

 

1、安裝:npm install vue-simple-uploader --save

2、

    <uploader
          ref="uploader"
          :options="options"
          :autoStart="false"
          @file-added="onFileAdded"
          @file-success="onFileSuccess"
          @file-progress="onFileProgress"
          @file-error="onFileError"
          @class="uploader-app"
        >
          <uploader-unsupport></uploader-unsupport>
          <uploader-btn id="global-uploader-btn" :attrs="attrs" ref="uploadBtn">{{$t('imgUpload.file')}}</uploader-btn>
          <uploader-btn :directory="true">{{$t('imgUpload.folder')}}</uploader-btn>
          <uploader-list v-show="panelShow">
            <div id="filePanel" 
              v-drag
              draggable="false"
              class="file-panel"
              :class="{'mini': collapse}"
              slot-scope="props"
            >
              <div class="file-title">
                <h2>文件列表</h2>
                <div class="operate">
                  <el-button @click="fileListShow" type="text">
                    <i :class="collapse ? 'el-icon-plus': 'el-icon-minus'"></i>
                  </el-button>
                  <el-button @click="close" type="text" title="關閉">
                    <i class="el-icon-close"></i>
                  </el-button>
                </div>
              </div>
              <ul class="file-list">
                <li v-for="file in props.fileList" :key="file.id">
                  <uploader-file :class="'file_' + file.id" ref="files" :file="file" :list="true"></uploader-file>
                </li>
                <div class="no-file" v-if="!props.fileList.length">
                  <i class="nucfont inuc-empty-file"></i> 暫無待上傳文件
                </div>
              </ul>
            </div>
          </uploader-list>
        </uploader> 

3、

      options: {
        target: process.env.API_ROOT + "/api/File/UploadByBuffer",//地址
        testChunks: false, //不校驗
        chunkSize: "10240000",
        fileParameterName: "file", //上傳文件時文件的參數名,默認file
        maxChunkRetries: 3, //最大自動失敗重試上傳次數
        query:{
          //form data裏的參數 根據實際需要
        },
        headers: {
          // 在header中添加的驗證 根據實際需要
        }
      },
      panelShow: false, //上傳列表的顯示
      attrs: {
        // 接受的文件類型 根據實際需要
        accept: [".zip", ".rar"]
      },
      collapse: false ,//列表的縮放 
      curTop:undefined,//標記當前列表的位置
      curLeft:undefined,//標記當前列表的位置

4、

    //添加文件到列表 還未上傳   
    onFileAdded(file) {
      this.panelShow = true;
      //設置headers等參數的值
      
    },
    //上傳成功
    onFileSuccess(rootFile, file, response, chunk) {
      
    },
    //文件進度的回調
    onFileProgress(rootFile, file, chunk) {
       
    },
    //出錯
    onFileError(rootFile, file, response, chunk) {

    },
    //上傳列表縮放
    fileListShow() {
      this.collapse = !this.collapse;
      let oDiv = document.getElementById('filePanel')
      if(this.collapse){
        //屏幕高度
        let h = document.body.clientHeight ||
          window.innerHeight ||
          document.documentElement.clientHeight ;
        //屏幕寬度
        let w = document.body.clientWidth ||
          window.innerWidth ||
          document.documentElement.clientWidth ;
          this.curTop = oDiv.style.top;
          this.curLeft = oDiv.style.left

        oDiv.style.top = (h-40) + "px";
        oDiv.style.left = (w-170) + "px";
      }else{
        //回到原來的位置
        oDiv.style.top = this.curTop ;
        oDiv.style.left = this.curLeft;
      }
    },
    //關閉上傳列表
    close() {
      this.panelShow = false;
    },

5、寫了拖拽(不是必要)

 directives: {
    drag(el) {
      let oDiv = el; //當前元素
      let self = this; //上下文

      //禁止選擇網頁上的文字
      document.onselectstart = function() {
        return false;
      };
      oDiv.onmousedown = function(e) {
        //鼠標按下,計算當前元素距離可視區的距離
        let disX = e.clientX - oDiv.offsetLeft;
        let disY = e.clientY - oDiv.offsetTop;
        document.onmousemove = function(e) {
          //通過事件委託,計算移動的距離
          let l = e.clientX - disX;
          let t = e.clientY - disY;
          //屏幕高度
          let h = document.body.clientHeight ||
            window.innerHeight ||
            document.documentElement.clientHeight ;
          //屏幕寬度
          let w = document.body.clientWidth ||
            window.innerWidth ||
            document.documentElement.clientWidth ;
          //左邊菜單伸縮狀態的寬度 圖簡單直接寫了數字 嚴謹的小夥伴可以直接獲取側菜單的寬度
          let leftBar = Cookies.get('sidebarStatus') == '0' ? 54 : 210
          //判斷有沒有超過邊界點
          if (l > (w - oDiv.offsetWidth)) l = w  - oDiv.offsetWidth;
          if(l < leftBar) l = leftBar;
          if (t > (h - oDiv.offsetHeight)) t = h - oDiv.offsetHeight;
          if (t < 50) t = 50;
          //移動當前元素
          oDiv.style.left = l + "px";
          oDiv.style.top = t + "px";
        };
          document.onmouseup = function(e) {
          document.onmousemove = null;
          document.onmouseup = null;
        };
        //return false不加的話可能導致黏連,就是拖到一個地方時div粘在鼠標上不下來,相當於onmouseup失效
        return false;
      };
    }
  },

6、寫的樣式(當作參考拋磚引玉)

.uploader {
  float: right;
  .uploader-btn {
    background: #f5921f;
    color: #fff;
    height: 30px;
    font-weight: normal;
    line-height: 24px;
    border: 0px;
    font-size: 12px;
  }
  .uploader-btn:hover {
    background: #ebae67;
  }
}
.file-panel {
  position: fixed;
  bottom: 10px;
  right: 10px;
  background: #fff;
  box-shadow: 1px 1px 5px #ccc;
  border-radius: 5px;
  z-index: 2;
  width: 650px;
  height: 340px;
  .file-title {
    border: 1px solid #cccccc4a;
    font-size: 10px;
    height: 40px;
    line-height: 40px;
    padding-left: 10px;
    h2 {
      margin: 0px;
      display: inline-block;
      font-weight: normal;
      color: #666363;
    }
    .operate {
      float: right;
      margin-right: 10px;
    }
  }
  .file-list {
    list-style-type: none;
    height: 300px;
    overflow-y: scroll;
    padding: 0px;
    margin: 0px;
    width: 100%;
    .uploader-file-info i {
      display: none;
    }
  }
}
.mini {
  right: -490px;
  bottom: -306px;
  .operate {
    margin-right: 500px !important ;
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章