1. 程式人生 > >vue + element-ui + axios 多檔案加表單引數上傳

vue + element-ui + axios 多檔案加表單引數上傳

vue加element ui 寫的一個專案,請求用的 axios 。在做表單提交的時候常常遇到需要在表單中傳檔案或者圖片,一般處理起來是先單個傳完檔案後得到路徑然後再表單提交一起傳給後端。如果介面是必須和表單其他引數一起傳過去的時候操作起來就是下面要講的了。

ps:介面是我寫的,我不想改介面,我就得去找前端一起傳參的解決辦法咯,網上找了資料,感覺都是不太完整,對於我這種剛入前端大坑的菜雞來說不友好,對著除錯半天都不行,最後參考官方文件和各種資料解決後,整理下,方便下次查閱,下面是程式碼部分,其他說明見程式碼註釋(為了查閱程式碼方便,部分無關的或重複性程式碼以…代替)

模板程式碼如下:

<el-tab-pane label="微信支付" name="weixin" :lazy=true>
  <!-- 微信配置 -->
  <el-form ref="weixinForm" :label-position="labelPosition" class="" label-width="200px">
    <el-form-item label="APP_ID">
      <el-input class="form-input" v-model="weixin.app_id"></el-input
>
</el-form-item> ... <el-form-item label="證書檔案(apiclient_cert.pem )"> <el-upload ref="upload" action="" :http-request="handleFile" :on-change="cert_path_file" :multiple="false" :limit="1" :file-list="cert_path" accept=".pem"> <el-button size="small" type
="primary" @click="clearUploadedImage('upload')">
點選上傳</el-button> <div slot="tip" class="el-upload__tip">只能上傳.pem檔案</div> </el-upload> </el-form-item> <el-form-item label="金鑰檔案(apiclient_key.pem)"> <el-upload ref="upload1" action="" :http-request="handleFile" :on-change="key_path_file" :multiple="false" :limit="1" :file-list="key_path" accept=".pem"> <el-button size="small" type="primary" @click="clearUploadedImage('upload1')">點選上傳</el-button> <div slot="tip" class="el-upload__tip">只能上傳.pem檔案</div> </el-upload> </el-form-item> <el-form-item> <el-button type="primary" @click="onSubmit('weixin')">儲存修改</el-button> </el-form-item> </el-form> </el-tab-pane>

JavaScript程式碼:

<script>
import tzBreadcrumb from './../../components/breadcrumb/breadcrumb.vue';
import http from './../../config/index';
import api from './../../api/api';
export default {
  mounted: function () {
    this.initdata();
  },
  components: {
    'tz-breadcrumb': tzBreadcrumb
  },
  data: () => {
    return {
      alipay: {},
      weixin: {},
      wsbank: {},
      labelPosition: '',
      loading: false,
      cert_path: [],
      key_path: []
    };
  },
  methods: {
    initdata: function () {
      this.getData(api.getAlipayConf);
    },
    handleClick (tab, event) {
      if (tab.name === 'alipay' && Object.keys(this.alipay).length === 0) {
        this.getData(api.getAlipayConf);
      } else if (tab.name === 'weixin' && Object.keys(this.weixin).length === 0) {
        this.getData(api.getwechatpayconfig);
      }
    },
    handleFile () { },
    cert_path_file (file, fileList) {
      // 證書上傳元件 on-change 事件
      this.cert_path = fileList;
    },
    key_path_file (file, fileList) {
      // 祕鑰上傳元件 on-change 事件
      this.key_path = fileList;
    },
    clearUploadedImage (type) {
      // 重新選擇檔案時清空檔案列表
      if (type === 'upload') {
        this.$refs.upload.clearFiles();
        this.cert_path = [];
      } else if (type === 'upload1') {
        this.$refs.upload1.clearFiles();
        this.key_path = [];
      }
    },
    onSubmit (type) {
      let data = {};
      let url = '';
      if (type === 'alipay') {
        ...
      }
      
      if (type === 'weixin') {
        url = api.setwechatpayconfig;
        // 表單帶引數上傳檔案
        // 獲取表單 
        let form = this.$refs['weixinForm'].$el; 
        // 建立 FormData 物件
        let formData = new FormData(form);
        // 建立了 FormData 物件的時候傳入了表單但是讀不出來表單資料,不知道哪裡的問題。所以下面用 append 方法新增引數,想打印出來看看的話可以 formData.get('id')
        formData.append('token', localStorage.getItem('token'));
        formData.append('id', this.weixin.id);
        formData.append('app_id', this.weixin.app_id);
        formData.append('merchant_id', this.weixin.merchant_id);
        formData.append('secret', this.weixin.secret);
        formData.append('key', this.weixin.key);
        formData.append('notify_url', this.weixin.notify_url);
        // 這裡檔案上傳的欄位一定要設定檔案列表中的 raw 引數 this.cert_path[0].raw
        formData.append('cert_path', this.cert_path[0] ? this.cert_path[0].raw : '');
        formData.append('key_path', this.key_path[0] ? this.key_path[0].raw : '');
        // 記得配置請求頭中 Content-Type 為'multipart/form-data'
        let config = {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        };
        http.form(url, formData, config, response => {
          // console.log(response.data);
          this.loading = false;
          if (response.code === '10001') {
            this.cert_path = [];
            this.key_path = [];
            this.$message('設定完成');
          } else {
            this.$message.error(response.msg);
          }
        }, () => {
          this.$message.error('網路錯誤');
          this.loading = false;
        });
      }
    },
    setData (url, data) {
      ...
    },
    getData (url) {
      ...
    }
  }
};
</script>

引入的元件 import http from ‘./…/…/config/index’ 中http.form 方法

form (url, data, config, success, fail) {
  axios.post(baseURL + url, data, config).then(function (response) {
    return success(checkStatus(response));
  }).catch(function (res) {
    return fail(checkCode(res));
  });
}

console.log(this.cert_path); // 列印結果如下圖
在這裡插入圖片描述

對於 element ui 上傳元件用法具體的請查閱官方文件
Element UI ( Upload 上傳 )