ホームページ  >  記事  >  ウェブフロントエンド  >  el-upload を使用して vue3 にファイルをアップロードする方法

el-upload を使用して vue3 にファイルをアップロードする方法

WBOY
WBOY転載
2023-05-15 21:31:043285ブラウズ

el-upload ファイルのアップロード

プロジェクト開発中にファイルのアップロードが必要になることがよくありますが、この記事では、elementplus での el-upload を使用したファイルのアップロードについて詳しく紹介します。

まず、el-upload で設定できるプロパティとイベントを見てみましょう。

#Attributes

    #action: リクエスト URL
  • headers: アップロード リクエスト ヘッダーを設定
  • #method: アップロード リクエスト メソッドを設定します。
  • multiple: ファイルの複数選択をサポートするかどうか
  • data: 追加パラメータが含まれる場合アップロード
  • name: アップロードされたファイルのフィールド名
  • with-credentials: Cookie 認証情報の送信をサポート
  • 上記のパラメータはデフォルトのアクションでリクエストする場合に使用されますが、カスタムリクエストメソッドを使用する場合は基本的にこれらの属性は使用されません。

#show-file-list: アップロードされたファイルのリストを表示するかどうか

  • drag: ドラッグ アンド ドロップによるアップロードを有効にするかどうか

  • accept: アップロードされたファイルの種類を受け入れる

  • on-preview: ファイル リストでアップロードされたファイルをクリックするときのフック

  • on-remove: ファイルリストからファイルを削除するときのフック

  • on-success: ファイルのアップロードが成功したときのフック

  • on-error: ファイルのアップロード失敗時のフック

  • on-progress: ファイルのアップロード時のフック

  • on-change: ファイルのアップロード時のフックファイルステータスの変更、追加、アップロードの成功と失敗の両方が呼び出されます

  • on-exceed: 制限を超えたときにフックが実行されます

  • before -upload: ファイルのアップロード 前のフックの場合、パラメータはアップロードされたファイルです。

    false
  • が返されるか、
  • Promise

    が返されて拒否された場合、アップロードは停止します。 before-remove: ファイルを削除する前のフック。パラメータはアップロードされたファイルとファイルリストです。

    false
  • を返すか、
  • Promise を返す場合

    拒否された場合、削除は停止します。 file-list/v-model:file-list: デフォルトのファイルアップロード

  • list-type: ファイルリストのタイプ、'テキスト ' | '絵' | '絵カード'。

  • auto-upload: ファイルを自動的にアップロードするかどうか

  • http-request: デフォルトの Xhr 動作をオーバーライドし、リクエストを実装できるようにします。アップロード ファイル

  • disabled: アップロードを無効にするかどうか

  • limit: アップロードできるファイルの最大数

  • #メソッド

abort: アップロードリクエストをキャンセル

  • submit: 手動アップロードファイルリスト

  • clearFiles: アップロードされたファイルのクリアされたリスト (このメソッドは、

    before-upload
  • での呼び出しをサポートしていません)
  • handleStart: ファイルを手動で選択します

  • handleRemove: ファイルを手動で削除します。

    file
  • rawFile

    がマージされました。 写真のアップロードの実装

  • 写真をアップロードするとき、通常は http リクエストを書き換え、リクエストにデフォルトのアクションを使用しないため、通常はアクションを &lsquo に設定します。 ;#’。
<template>
  <div>
    <el-upload
      action="#"
      :headers="headers"
      :list-type="listType"
      :http-request="uploadAction"
      :on-exceed="handleExceed"
      :on-remove="handleRemove"
      :before-upload="beforeUpload"
      :on-success="uploadSuccess"
      :on-error="uploadError"
      :on-progress="uploadProgress"
      :file-list="fileListCopy.data"
      ref="upload"
      :multiple="true"
      :limit=&#39;limit&#39;
      :disabled="disabled"
      :data="paramData"
    >
    <el-icon><Plus /></el-icon>
    <template #file="{ file }">
      <div>
        <img :src="file.url" alt="" />
        <span class="el-upload-list__item-actions">
          <span
            class="el-upload-list__item-preview"
            @click="handlePictureCardPreview(file)"
          >
            <el-icon><zoom-in /></el-icon>
          </span>
          <span
            class="el-upload-list__item-delete"
            @click="handleRemove(file)"
          >
            <el-icon><Delete /></el-icon>
          </span>
        </span>
      </div>
    </template>
    </el-upload>
    <el-dialog v-model="previewVisible">
      <img w-full :src="dialogImageUrl" alt="Preview Image" />
    </el-dialog>
  </div>
</template>
<script>
export default {
  name: &#39;uploadImg&#39;
}
</script>
<script setup>
import { Delete, Plus, ZoomIn } from &#39;@element-plus/icons-vue&#39;;
import { reactive, ref, defineProps, defineEmits, computed, getCurrentInstance } from &#39;vue&#39;;
import { ElMessage } from &#39;element-plus&#39;;
const props = defineProps({
  // 允许上传文件件的最大数量
  limit:{
    type:Number
  },
  // 是否禁用上传
  disabled:{
    type:Boolean,
    default:false
  },
  // 文件列表类型
  listType:{
    type:String,
    default:&#39;picture-card&#39;
  },
  // 上传时携带的额外参数
  paramData: {
    type:String
  }
});
const emits = defineEmits([]);
const cns = getCurrentInstance();
const globObj = cns.appContext.config.globalProperties;
const previewVisible = ref(false);
const dialogImageUrl = ref(&#39;&#39;);
const fileListCopy = reactive({
  data: []
});
const onece = ref(false);
const myChangeFile = ref(&#39;&#39;);
const changeFileIndex = ref(-1);
const uploadImgArr = reactive({
  data: []
});
const headers = reactive({});
// 预览大图
const handlePictureCardPreview = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url;
  previewVisible.value = true;
};
// 移除图片
const handleRemove = (file, fileList) => {
  console.log(&#39;handleRemove&#39;, handleRemove);
  console.log(&#39;file&#39;, file);
  console.log(&#39;fileList&#39;, fileList);
  fileListCopy.data = fileListCopy.data.filter(v => v.uid !== file.uid);
};
// 文件上传数量限制
const handleExceed = (files, fileList) => {
  if (props.limit) {
    ElMessage.error(`只能上传${props.limit}张图片`);
  }
  console.log(&#39;handleExceed&#39;, handleExceed);
  console.log(&#39;files&#39;, files);
  console.log(&#39;fileList&#39;, fileList);
};
// 上传请求
const uploadAction = (option) => {
  let formData = new FormData();
  const url = &#39;&#39;;
  globObj.$axios({
    url: url,
    method: &#39;post&#39;,
    transformRequest: [function(data, headers) {
      // 去除post请求默认的Content-Type
      delete headers[&#39;Content-Type&#39;]
      return data
    }],
    data: formData,
    timeout: 300000
  }).then(res => {
    ElMessage.success(&#39;资产添加成功&#39;);
  }).catch((err) => {
    console.log(err);
  });
}
// 格式大小的限制
const beforeUpload = (file) => {
  let isJPG = false,
  fileType = file.type.split(&#39;/&#39;)[0];
  if(file.type === "image/jpeg" || file.type === "image/png") {
    isJPG = true;
  } else {
    isJPG = false;
  }
  const isLt2M = file.size / 1024 / 1024;
  if (fileType != &#39;image&#39; || isLt2M > 2) {
    ElMessage.error("请上传2M以内的图片文件!");
    return false
  }
  return true;
};
// 文件上传成功时的钩子
const uploadSuccess = (response, file, fileList) => {
  // 上传成功之后后台返回的数据
  console.log(&#39;uploadSuccess&#39;, uploadSuccess);
};
const uploadProgress = (e, file, fileList) => {
  console.log(&#39;uploadProgress&#39;, uploadProgress)
};
const uploadError = (err, file, fileList) => {
  console.log(&#39;uploadError&#39;, uploadError);
};
</script>

既存のピット

通常、ファイルをアップロードするとき、リクエスト ヘッダーの Content-Type: multipart/form-data; 要件では、次の乱数を設定する必要もあります。これは、Content-Type: multipart/form-data;boundary=----WebKitFormBoundarypzSlbADtTRuFx5FC です。

私が遭遇した問題は次のとおりです。

質問 1

Content-Type: multipart/form-data が設定されています。この時点では、リクエストには乱数境界がありません =----WebKitFormBoundarypzSlbADtTRuFx5FC。

グローバル コンテンツ タイプを設定すると、アップロード インターフェイス設定 multipart/form-data が機能しないことがわかります。境界がないため、アップロードはサーバー 500 で失敗するはずです。

その後、境界を手動で追加しようとしましたが、今度はエラーが 400 に変わりました。

質問 2

情報をクエリした後、境界を追加する必要はないと言われました。 set Content-Type: multipart/form-data; パラメータが formData フォーム内にある限り、ブラウザはリクエスト ヘッダーの Content-Type を Content-Type: multipart/form-data; border=-- に自動的に変換します。 --WebKitFormBoundarypzSlbADtTRuFx5FC。

ただし、設定しない場合は、デフォルトの application/json になります。

そこで情報を確認したところ、axios のtransformRequest 属性により、リクエスト データをサーバーに送信する前にリクエスト データを変更できることがわかりました。リクエストはデフォルトのポスト リクエスト メソッドにあるため、Content-Type の値はは application/json であり、ブラウザが自動的に追加できるように、デフォルトの値を削除する必要があります。

  globObj.$axios({
    url: url,
    method: &#39;post&#39;,
    transformRequest: [function(data, headers) {
      // 去除post请求默认的Content-Type
      delete headers[&#39;Content-Type&#39;]
      return data
    }],
    data: formData,
    timeout: 300000
  }).then(res => {
    ElMessage.success(&#39;资产添加成功&#39;);
  }).catch((err) => {
    console.log(err);
  });

質問 3

他のパラメータを渡す場合は、他のパラメータも追加する必要があります。追加しないと、パラメータ エラーが報告される可能性があります。

rree

以上がel-upload を使用して vue3 にファイルをアップロードする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。