vue-cli 上传文件与文件夹进度条

效果

DEMO

点我呀?
⚠️?测试上传的东西后端一概不收!!![…]

代码

Way - 01
*** store.js
/* eslint-disable */
import Vue from 'vue';
import Vuex from 'vuex';
import axios from 'axios';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    uploadPercentage: 0
  },
  mutations: {
    setUploadPercentage(state, percentage) {
      state.uploadPercentage = percentage;
    },
  },
  actions: {
    upload({ commit }, file) {
      const config = {
        onUploadProgress: function(progressEvent) {
          console.log(progressEvent);
          const uploadPercentage = Math.round((progressEvent.loaded * 100) / progressEvent.total);
          commit('setUploadPercentage', uploadPercentage);
        },
      };
      const data = new FormData();
      data.append('file', file);
      axios
        .post('https://api/v1/upload', data, config)
        .then(data => {
          console.log(data);
        })
        .catch(err => {
          commit('setUploadPercentage', 10); // 上传失败
          console.log(err);
        });
    },
  },

  getters: {
    uploadPercentage: state => state.uploadPercentage,
  },
});
*** temp.vue
<template>
  <div>
    <a href="javascript:;" class="file">
      上传文件夹
      <i class="el-icon-upload2 el-icon--right"></i>
      <input type="file" ref="file" name="file" webkitdirectory @change.stop="handleFileChanged">
    </a>
    <a href="javascript:;" class="file">
      上传文件
      <i class="el-icon-upload2 el-icon--right"></i>
      <input type="file" ref="upload" name="file" @change.stop="handleFileChanged">
    </a>
    <!--  -->
    <el-progress :text-inside="true" :stroke-width="18" :percentage="percentage"></el-progress>
    <el-progress
      :text-inside="true"
      :stroke-width="18"
      :percentage="percentage"
      color="rgba(142, 113, 199, 0.7)"
    ></el-progress>
    <el-progress :text-inside="true" :stroke-width="18" :percentage="percentage" status="success"></el-progress>
    <el-progress :text-inside="true" :stroke-width="18" :percentage="percentage" status="exception"></el-progress>
    <el-progress type="circle" :percentage="percentage"></el-progress>
    <el-progress type="circle" :percentage="percentage" color="#8e71c7"></el-progress>
    <el-progress type="circle" :percentage="percentage" status="success"></el-progress>
    <el-progress type="circle" :percentage="percentage" status="exception"></el-progress>
  </div>
</template>
*** temp.vue
import axios from "axios";
import { mapState, mapGetters, mapActions, mapMutations } from "vuex";
export default {
  data() {
    return {
      file: null
    };
  },
  computed: {
    ...mapGetters({
      percentage: "uploadPercentage"
    })
  },
  methods: {
    handleFileChanged(event) {
      const file = event.target.files[0];
      this.$store.dispatch("upload", file);
    }
  }
};
*** temp.vue
<style lang="less" scoped>
.el-progress {
  margin-top: 10px;
}
.file {
  position: relative;
  display: inline-block;
  background: #1890ff;
  border-radius: 4px;
  padding: 4px 12px;
  overflow: hidden;
  color: #fff;
  text-decoration: none;
  text-indent: 0;
  line-height: 20px;
  font-size: 14px;
  input {
    position: absolute;
    font-size: 14px;
    right: 0;
    top: 0;
    opacity: 0;
    cursor: pointer;
  }
  i {
    float: left;
    font-size: 16px;
    margin-top: 2px;
    margin-right: 4px;
    margin-left: -6px;
  }
}
</style>

Way - 02

temple
 <el-dialog title="上传进度" :visible.sync="dialogVisible" @closed="closeDal" width="60%">
  <div>
    <el-progress
      :text-inside="true"
      :stroke-width="18"
      status="success"
      :percentage="percentage"
    ></el-progress>
    <p>{{percentage === 100 ? '上传完成!': percentage === 0? '上传失败': '上传中...'}}</p>
  </div>
  <span slot="footer" class="dialog-footer">
    <el-button type="primary" @click="closeDal">确 定</el-button>
  </span>
</el-dialog>
单个文件
uploadFile(e, m) {
  let file = e.target.files;
  let param = new FormData(); // 创建FormData对象
  this.dialogVisible = true;
  const config = {
    onUploadProgress: progressEvent => {
      const complete = Math.round(
        (progressEvent.loaded * 100) / progressEvent.total
      );
      this.percentage = complete;
    }
  };
  for (var i = 0; i < file.length; i++) {
    // 通过append向FormData对象添加数据
    param.append("file", file[i]);
  }
  axios
    .post("/task/upload-file", param, config)
    .then(res => {
      if (res.data.code === "0") {
        this.openMessageSuccess(res.data.msg);
        this.getTasks();
      } else {
        this.percentage = 0;
        this.openMessageError(res.data.msg);
      }
    })
    .catch(err => {
      this.percentage = 0;
      this.openMessageError(err);
    });
},

文件夹
  uploadFiles(event) {
    const fileList = event.target.files;
    let param = new FormData(); // 创建FormData对象
    let paths = [];
    _.each(fileList, function(o) {
      paths.push(o.webkitRelativePath);
    });
    for (var i = 0; i < fileList.length; i++) {
      // 通过append向FormData对象添加数据
      param.append("file", fileList[i]);
      param.append("path", paths[i]);
    }
    const config = {
      onUploadProgress: progressEvent => {
        const complete = Math.round(
          (progressEvent.loaded * 100) / progressEvent.total
        );
        this.percentage = complete;
      }
    };
    // param.append({paths});
    axios
      .post("/task/upload-dir", param, config)
      .then(res => {
        if (res.data.code === "0") {
          this.openMessageSuccess(res.data.msg);
          this.getTasks();
        } else {
          this.percentage = 0;
          this.openMessageError(res.data.msg);
        }
      })
      .catch(err => {
        this.percentage = 0;
        this.openMessageError(err);
      });
  },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值