Vueはアップロードコンポーネントを実装します

Vueはアップロードコンポーネントを実装します

1. はじめに

効果は以下のとおりです

2. アイデア

ファイルをアップロードする2つの方法

1. フォームから

<フォーム 
  メソッド="投稿" 
  enctype="multipart/from-data"
  アクション="api/アップロード"
>
  <input type="ファイル名="ファイル">
  <button type="submit">送信</button>
</フォーム>

フォームの method 属性は、HTML フォームを通じてサーバーにデータを送信し、サーバーの変更された結果を返す「post」リクエストを指定します。この場合、Content-Type は、<form> 要素に適切な enctype 属性を設定することによって設定されます。

フォームの enctype 属性は、フォーム データをサーバーに送信する前にどのようにエンコードするかを指定します。

  • application/x-www-form-urlencoded (デフォルト): 送信前にすべての文字がエンコードされることを意味します。データは「&」で区切られたキーと値のペアにエンコードされ、キーと値は「=」で区切られます (「name=seven&age=19」)。バイナリデータはサポートされていません。
  • multipart/form-data: バイナリデータをサポートします (ファイルをアップロードするときに指定する必要があります)

2. JavaScript非同期リクエストフォーム

FormData インターフェイスは、フォーム データを表すキーと値のペアを作成する方法を提供し、XMLHttpRequest.send() メソッドを通じてデータを簡単に送信できることがわかっています。このインターフェイスとこのメソッドは非常にシンプルで直接的です。送信エンコーディングが「multipart/form-data」に設定されている場合、フォームと同じ形式が使用されます。

var formdata = new FormData(); // FormData オブジェクトを作成します formdata.append("name","laotie"); // append() メソッドを使用して新しい属性値を追加します... // その他の方法については、以下のリンクをクリックしてください

FormData インターフェース

3. ライフサイクル

アップロードコンポーネントにもライフサイクルがある

beforeUpload --> アップロード中 --> fileUploaded または uploadedError

4. コードドラフト

この例では、アップロードコンポーネントはjs非同期リクエストを使用して開発されています。

<input type="file" name="file" @change.prevent="handleFileChange">
// ファイルのアップロードをトリガーするファイルタイプの入力を作成します。後で入力を非表示にしてスタイルをカスタマイズできます。// スタイルをカスタマイズするときに、スロットを使用して、さまざまなアップロード状態 (読み込み中、成功、デフォルト) のスタイルを区別できます。
const handleFileChange = (e:Event)=>{
  const target = e.target を HTMLInputElement として
  const files = Array.from(target.files)// ここで取得されるのはクラス配列であることに注意してください if(files){
    // ファイルを取得する const uploadedFile = files[0]
    
    if(!validateFormat) 戻り値
    // ...これは単なる考え方であり、具体的な検証についてはここでは説明しません // ファイルをアップロードする前に、ファイル形式、サイズなどの検証を行ってください。
    // 要件を満たさない場合、それ以上のリクエストは送信されません const formData = new FormData()
    formData.append(アップロードされたファイル名、アップロードされたファイル)
    
    axios.post('/upload',formData,{
      ヘッダー:{
         // エンコード タイプ 'Content-Type': 'multipart/form-data' を設定することに注意してください
      }
    }).then(res=>{
      console.log('アップロード成功')
    }).catch(エラー =>{
      // ファイルのアップロードに失敗しました}).finally(()=>{
      // ファイルのアップロードが完了しました。成功か失敗かは関係ありません // ここで input.value をクリアできます
    })
  }
}

5. 具体的な実施

// アップロード.vue
<テンプレート>
  <div class="アップロードコンテナ">
    <div class="upload-box" @click.prevent="triggerUpload" v-bind="$attrs">
      <スロット名="読み込み中" v-if="fileStatus==='読み込み中'">
        <button class="btn btn-primary">アップロード中</button>
      </スロット>
      <スロット名="アップロード済み" v-else-if="fileStatus==='成功'" :uploadedData="ファイルデータ">
        <button class="btn btn-primary">アップロードに成功しました</button>
      </スロット>
      <スロット v-else name="default">
        <button class="btn btn-primary">クリックしてアップロード</button>
      </スロット>
    </div>
    <input type="file" class="file-input d-none" name="file" ref="uploadInput" @change="hanldeInput"/>
  </div>
</テンプレート>
<script lang="ts">
'vue' から {defineComponent、ref、PropType、watch} をインポートします。
'axios' から axios をインポートします
タイプ UploadStatus = '準備完了' | '読み込み中' | '成功' | 'エラー'
タイプ FunctionProps = (file:File) => ブール値
エクスポートデフォルトdefineComponent({
  名前: 'アップロード'、
  継承属性: false、
  小道具: {
    // アップロードURL
    アクション: {
      タイプ: 文字列、
      必須: true
    },
    // アップロード前の検証、ブール値を返す関数 beforeUpload: {
      タイプ: Function as PropType<FunctionProps>
    },
    // アップロードされたデータ。ステータスの決定や表示の初期化に使用されます。uploadedData: {
      タイプ: オブジェクト
    }
  },
  出力: ['file-uploaded-success', 'file-uploaded-error'],
  セットアップ(props, ctx) {
    const uploadInput = ref<null | HTMLInputElement>(null)
    const fileStatus = ref<UploadStatus>(props.uploadedData ? '成功' : '準備完了')
    const ファイルデータ = ref(props.uploadedData)
    watch(() => props.uploadedData、(val) => {
      if (値) {
        fileStatus.value = '成功'
        ファイルデータ.値 = val
      }
    })
    const トリガーアップロード = () => {
      アップロード入力値の場合{
        アップロード入力値クリック()
      }
    }
    const hanldeInput = (e:Event) => {
      const target = e.target を HTMLInputElement として
      const ファイル = ターゲット.ファイル
      console.log(ターゲット)
      if (ファイル) {
        const uploadFile = Array.from(ファイル)
        定数validateFormat = props.beforeUpload ? props.beforeUpload(uploadFile[0]) : true
        if (!validateFormat) 戻り値
        fileStatus.value = '読み込み中'
        const フォームデータ = 新しいフォームデータ()
        formData.append('ファイル', uploadFile[0]) を追加します。
        axios.post(props.action, フォームデータ, {
          ヘッダー: {
            'コンテンツタイプ': 'マルチパート/フォームデータ'
          }
        }).then(res => {
          console.log('ファイルが正常にアップロードされました', res)
          fileStatus.value = '成功'
          ファイルデータ.値 = res.data
          ctx.emit('ファイルのアップロード成功', res.data)
        }).catch(エラー => {
          console.log('ファイルのアップロードに失敗しました', エラー)
          fileStatus.value = 'エラー'
          ctx.emit('ファイルアップロードエラー', エラー)
        }).finally(() => {
          console.log('ファイルのアップロードが完了しました')
          アップロード入力値の場合{
            アップロード入力値.value = ''
          }
        })
      }
    }

    戻る {
      アップロード入力、
      トリガーアップロード、
      ハンドル入力、
      ファイルステータス、
      ファイルデータ
    }
  }
})
</スクリプト>

使用例:

<テンプレート>
  <div class="投稿ページを作成">
    <アップロード
      アクション="/アップロード"
      :beforeUpload="アップロード前"
      :uploadedData="アップロードされたデータ"
      @file-uploaded-success="アップロード成功"
      クラス="d-flex align-items-center justify-content-center bg-light text-secondary w-100 my-4"
      >
      <テンプレート #uploaded="slotProps">
        <div class="アップロードされたエリア">
          <img :src="slotProps.uploadedData.data.url"/>
          <h3>クリックして再アップロード</h3>
        </div>
       </テンプレート>
       <テンプレート #デフォルト>
         <h2>クリックしてヘッダー画像をアップロード</h2>
       </テンプレート>
       <テンプレート #読み込み中>
         <div class="d-flex">
          <div class="spinner-border text-secondary" role="status">
            <span class="sr-only"></span>
          </div>
         </div>
       </テンプレート>
    </アップロード>
  </div>
</テンプレート>
<script lang="ts">
'vue' から {defineComponent、ref、onMounted} をインポートします。
'../components/Upload.vue' からアップロードをインポートします。
'../components/createMessage' から createMessage をインポートします。

エクスポートデフォルトdefineComponent({
  名前: 'CreatePost',
  コンポーネント: { アップロード },
  設定() {
    const uploadedData = ref() //レスポンシブデータを作成する let imageId = ''
    マウント時(() => {
      ....
      // ここではロジックは省略し、初期化データイメージを取得します
      if (画像) {
        uploadedData.value = { データ: 画像 }
      }
    })
    // アップロード前に検証し、ブール値を返します const beforeUpload = (file:File) => {
      const res = beforeUploadCheck(ファイル、{
        フォーマット: ['image/jpeg', 'image/png'],
        サイズ: 1
      })
      const { エラー、合格 } = res
      if (エラー === 'フォーマット') {
        createMessage('アップロードできる画像は JPG/PNG 形式のみです!', 'error')
      }
      if (エラー === 'サイズ') {
        createMessage('アップロードされた画像のサイズは 1MB を超えることはできません', 'error')
      }
      返品は合格しました
    }
    // アップロードが成功したら、フォームの作成などの後続の処理のために imageId を取得できます。const hanldeUploadSuccess = (res:ResponseProps<ImageProps>) => {
      createMessage(`画像ID ${res.data._id} をアップロード`, '成功')
      (res.data._id)の場合{
        画像ID = res.data._id
      }
    }
    戻る {
      アップロード前、
      アップロード成功、
      アップロードされたデータ
    }
  }
})
</スクリプト>
<スタイル>
.投稿ページを作成する{
  パディング:0 20px 20px;
}
.投稿ページを作成 .アップロードボックス{
  高さ:200px;
  カーソル: ポインタ;
  オーバーフロー: 非表示;
}
.create-post-page .upload-box img{
  幅: 100%;
  高さ: 100%;
  オブジェクトフィット: カバー;
}
.アップロードされたエリア{
  位置: 相対的;
}
.uploaded-area:hover h3{
  表示: ブロック;
}
.アップロードエリア h3{
  表示: なし;
  位置: 絶対;
  色: #999;
  テキスト配置: 中央;
  幅: 100%;
  トップ:50%
}
</スタイル>

以上がVueのアップロードコンポーネント実装の詳細です。Vueアップロードコンポーネントの詳細については、123WORDPRESS.COMの他の関連記事にも注目してください。

以下もご興味があるかもしれません:
  • vue-cropper コンポーネントは画像の切り取りとアップロードを実現します
  • vue-cropperプラグインは、画像キャプチャとアップロードコンポーネントのカプセル化を実現します。
  • Vue 画像の切り取りとアップロードコンポーネントの実装
  • ファイルアップロードコンポーネントを実装するための.netコアを使用したVue3.0
  • ネイティブコンポーネントを使用して写真をアップロードする Vue の例
  • Vue + Node.js + MongoDB 画像アップロードコンポーネントを使用して、画像のプレビューと削除機能を実装します。
  • Vue画像アップロードコンポーネントの使用方法の詳細な説明
  • Vue の elementUI コンポーネントを使用して手動で写真をアップロードする
  • Vue 開発パッケージのアップロード ファイル コンポーネントと使用例
  • Vue画像アップロードローカルプレビューコンポーネントの使用の詳細な説明
  • vue-cli3.0+element-ui アップロードコンポーネント el-upload の使用

<<:  Windows 64 ビットでの MySQL 8.0.13 のインストールと設定方法のグラフィック チュートリアル

>>:  CentOS 7.6 への MySQL 5.7 GA バージョンのインストール チュートリアル図

推薦する

VUEはトークンログイン認証を実装

この記事では、トークンログイン認証を実装するためのVUEの具体的なコードを例として紹介します。具体的...

docker mysqlの起動時に初期化SQLを実行する

1.Mysqlイメージを取得するdocker pull mysql:5.7 2. MySQLイメージ...

Nginx プロセス スケジューリングの問題の詳細な説明

Nginx は、マスター プロセス (MasterProcess) と、同じ数のホスト CPU コア...

JS を使用してクリップボード内の Excel コンテンツを解析する方法

目次序文1. イベントとクリップボードを貼り付ける2. クリップボード内のコンテンツ形式3. HTM...

Nginx の書き換え正規マッチング書き換え方法の例

Nginx の書き換え機能は、リダイレクトと同様に、URL アドレスを一時的または永続的に新しい場所...

Nginx 構成検出サービスのステータスを実装する方法

1. チェックステータスモジュールがインストールされているかどうかを確認します。 [root@loc...

HTML テーブルタグチュートリアル (45): テーブル本体タグ

<tbody> タグは、テーブル本体のスタイルを定義するために使用されます。基本構文 &...

MySQL 5.7.29 + Win64 解凍バージョンのインストールチュートリアル(画像とテキスト付き)

公式サイトをダウンロード自分に合ったバージョンを選択してダウンロードしてください。 ダウンロードをク...

Zabbix で Windows のパフォーマンスを監視する方法

背景情報最近、Windows パフォーマンスに関する本を読み直しています。以前は SCOM 監視を使...

Typora コードブロックのカラーマッチングとタイトルシリアル番号実装コード

効果: タイトルには独自のシリアル番号があり、コードブロックには配色があり、コードブロックの左上隅に...

docker-compose ネットワーク設定についての簡単な説明

ネットワーク使用チュートリアル公式サイト docker-compose.yml リファレンスドキュメ...

MYSQL ログとバックアップおよび復元の問題の詳細な説明

この記事では、参考までにMYSQLログとバックアップとリストアについて紹介します。具体的な内容は以下...

CSS3 で King of Glory マッチング人員読み込みページを実装する方法

King of Glory をプレイしたことがある人なら、このページの効果をよくご存知でしょう。なぜ...

CSS トップに戻る コード例

最近のウェブサイトのほとんどはページが長く、4 画面または 5 画面の長さのものもあれば、2 画面ま...

Linux で複数のファイルの名前を一度に変更する方法

序文日常業務では、すべての jpg ファイルを bnp に変更したり、名前の 1 を one に変更...