element-uiのアップロードコンポーネントuploadを正しく使用して、アリクラウドossクラウドサーバまたは自分のバックグラウンドサーバへのカスタムアップロードを完了します.


需要:elementのuploadコンポーネントを使用して、アリクラウドサーバにファイルをアップロードします.アップロードする前に、まず自分のバックグラウンドのインタフェースを要求して、アリ雲に戻って関連する証明書keyなどの情報をアップロードしてから正しくアップロードすることができます.どうやって解決しますか?答えはelementアップロードコンポーネントのhttp-requestカスタムアップロードです.
 <el-upload
  ref="upload"
  class="upload-demo"
  action
  :http-request="handleUpload"
  :auto-upload="false"
  multiple
  :on-exceed="handleExceed"
  :file-list="fileList"
  :on-change="onChangeFile"
  :on-remove="handleRemove"
  :on-preview="handlePreview"
  :before-remove="beforeRemove"
>
  <el-button slot="trigger" :disabled="type !== 'view' ? false : true" size="small" type="primary">    </el-button>
  <el-button :disabled="type !== 'view' ? false : true" style="margin-left: 10px;" size="small" type="success" @click="submitUpload">      </el-button>
</el-upload>

説明:actionは空に設定されています.アップロードを自分で制御する必要があるからです.:http-request=「handleUpload」自分たちで定義したアップロード方法.具体的には、以下を参照してください.Autoupload=「false」選択ファイルをオフにして自動的にアップロードし、手動トリガに変更しました.file-list=「file List」アップロードファイルのファイルリスト:on-change=「onChangeFile」ファイル選択またはアップロードに成功するとトリガーされ、ファイル選択後だけでなくトリガーされます.その他はドキュメントを参照してください.何も言うことはない.
dataで2つのファイルリストに関連する
data() {
     
return {
     
//        ,       ,    
      realFileList: [],
      //       ,el-upload  ,      。
      fileList: [
        // { name: 'aaa', url: 'image/196b62fd-fc70-4634-9bca'}
      ]}
}
fileListはuploadコンポーネントにバインドされて使用され、アップロードされていないファイルはrealFileListのアップロードに成功した後、バックグラウンドのファイルリストデータを転送します.
どうして別れたの?fileリストでは、制御しにくいからです.ファイルを選択してもアップロードされず、fileリストにはありません.アップロードに成功すると、fileListにデータが表示されます.削除をクリックすると、アップロードしたfileListはデータを保持します.そのため、realFileListとfileListのプロパティを2つ維持する必要があります.
定義されたmethodsに関連するアップロード関数
  methods: {
     
    //       ,         
    onChangeFile(file, fileList) {
     
      console.log('    ', file, fileList)
      if (file.response) {
     
        // this.fileList.push(file.response)
        //      ,         realFileList 
        this.realFileList.push(file.response)
      }
    },
        //        
    handleUpload(op) {
     
      // console.log('  ', op)
      // op element          ,           ,      ,       ,       ,
      //    upload              
      myupload(
        op.file,
        res => {
     
          let temp = {
     
            name: res.attachment,
            url: res.aliyunAddress
          }
          //       ,     ,            ,     √
          op.onSuccess(temp)
        },
        err => {
     
          console.log(err)
        },
        res => {
     
        //         ,               ,  res        {percent: 48}
          op.onProgress(res)
        }
      )
    },
        //         
    handleRemove(file, fileList) {
     
      //           
      console.log('    ', file, fileList)
      if (file.status === 'success') {
     
        this.realFileList.map((v, i, arr) => {
     
          if (v.url === file.url || v.url === file.response.url) {
     
            arr.splice(i, 1)
          }
        })
      }
    },
        //   (    )
    handlePreview(file) {
     
      // console.log(file)
      //       ,     
      if (file.status !== 'success') {
     
        return
      }
      let fileurl = file.url || file.response.url //             ,             
      window.open(fileurl )
    },
    handleExceed(files, fileList) {
     
      this.$message.warning(`       3    ,      ${
       files.length}${
       files.length + fileList.length}    `)
    },
    beforeRemove(file) {
     
      return this.$confirm(`     ${
       file.name}?`)
    }
upload関数は私がカスタマイズし、axiosを使用して実現しました.具体的な内容は以下の通りです.

// myupload.js
/*
 * @Description:     
 * @Autor: bolingsun
 * @Date: 2020-09-09 10:03:43
 */
import {
      v4 as uuidv4 } from 'uuid'
// import { fetchUploadPara } from '@/api/upload'
import axios from 'axios'
let basePath
if (process.env.NODE_ENV === 'production') {
     
  basePath = window.init_params.basePath
} else {
     
  basePath = '/portal/pages/vue/undefined'
}
/**
 * @description:       
 * file:   raw  
 * successCallback:        
 * errCallBack:        
 * progressCallback:          
 */
const myupload= function(file, successCallback = new Function(), errCallBack = new Function(), progressCallback = new Function()) {
     
  let fileName = file.name
  // options = options || {}
  axios({
     
    method: 'get',
    url: basePath + '/aliyun/get',
    params: {
     
      dir: 'image'
    }
  })
    .then(res => {
     
      let obj = res.data.data
      let config = {
     }
      config.host = obj['host']
      config.policyBase64 = obj['policy']
      config.accessid = obj['accessId']
      config.signature = obj['signature']
      config.expire = parseInt(obj['expire'])
      config.callbackbody = obj['callback']
      config.dir = obj['dir']
      let fd = new FormData(),
        uuid = uuidv4(),
        key = config.dir + uuid
      fd.append('key', key)
      fd.append('success_action_status', '200')
      fd.append('x-oss-object-acl', 'public-read')
      fd.append('x-oss-meta-fullname', fileName)
      fd.append('OSSAccessKeyId', config.accessid)
      fd.append('policy', config.policyBase64)
      fd.append('signature', config.signature)
      fd.append('success_action_status', '200')
      fd.append('file', file)
      if (config.host.indexOf('http:') > -1) {
     
        var protocol = window.location.protocol || 'http:'
        var subUrl = config.host.substring(5, config.host.length)
        config.host = protocol + subUrl
      }
      axios({
     
        url: config.host,
        method: 'POST',
        data: fd,
        processData: false,
        cache: false,
        contentType: false,
        onUploadProgress: function(progressEvent) {
     
          if (progressEvent.lengthComputable) {
     
            let percent = ((progressEvent.loaded / progressEvent.total) * 100) | 0
            progressCallback({
      percent: percent })
          }
        }
      })
        .then(() => {
     
          let size = file.size > 1000000 ? parseFloat(file.size / 1000000).toFixed(2) + 'M' : parseFloat(file.size / 1000).toFixed(2) + 'KB'
          successCallback({
     
            attachment: fileName,
            aliyunAddress: key,
            size: size
          })
        })
        .catch(err => {
     
          errCallBack(err)
        })
    })
    .catch(err => {
     
      errCallBack(err)
      // console.log(err)
    })
}
export default myupload


具体的な内容は自分の会社の状況に応じて具体的な論理を書きます.大体説明します.
myupload= function(file, successCallback = new Function(), errCallBack = new Function(), progressCallback = new Function()) {
     

4つのパラメータ、fileはファイルオブジェクトに渡され、彼の上にはバイナリデータがあります.successCallbackは成功後のコールバック、errCallBackは失敗後のコールバック、progressCallbackは進捗バーのコールバックです.進捗バーをアップロードします.関連するのはこの内容です.
  axios({
     
        url: config.host,
        method: 'POST',
        data: fd,
        processData: false,
        cache: false,
        contentType: false,
        //    axios         ,progressEvent          
        onUploadProgress: function(progressEvent) {
     
          if (progressEvent.lengthComputable) {
     
            let percent = ((progressEvent.loaded / progressEvent.total) * 100) || 0
            progressCallback({
      percent: percent })
          }
        }
      })

アップロード中にprogressEventイベントがトリガーされ、進捗状況をprogressEvent.loaded / progressEvent.totalで計算した後、progressCallbackコールバック関数で結果を返します.
そしてelement-ui uploadのところで、使います.op.onProgress({ percent: percent })これで進捗バーがスムーズに表示されます.
補足element-ui uploadに関するプロパティについて説明します.
onChangeFileこれは、2つのファイルを選択すると、2回トリガーされ、アップロードに成功し、トリガーされます.
handleUploadこれは、2つのファイルを選択し、2つのファイルが順番にこのメソッドを呼び出します.いくつかのファイルを選択し、アップロード操作をクリックすると、この関数の呼び出しが何回かトリガーされます.
handleRemoveこれは、あなたがアップロードに成功していないファイルを削除したのは、削除したのですが、あなたはアップロードに成功したファイルを削除して、リストは表示されなくなりましたが、fileList内にバインドされていて、まだデータがあって、本当に削除していません.
もう一つ、このアップロードの本質は、new FormDataがフォームオブジェクトをインスタンス化し、ファイルのバイナリデータをフォーム形式で提出することです.そういうことです.