この記事では、ドラッグアンドドロップやクリックによる画像のアップロードを実現するためのVueの具体的なコードを参考までに紹介します。具体的な内容は次のとおりです。 1. プレビュー画像2. 実装クリックしてアイデアをアップロードします。ファイルをアップロードするには、入力タイプを「ファイル」に設定します。入力ボックスを非表示にし、ボタンがクリックされたときに入力のクリックアップロード機能を呼び出します。残っているのは CSS を使用してページを最適化することだけです。 ドラッグ アンド ドロップ アップロードの考え方は、ドラッグ イベントをドロップボックスにバインドし、コンポーネントが破棄されたときにイベントをアンバインドすることです。ドラッグが終了したら、event.dataTransfer.files を通じてアップロードされたファイルの情報を取得します。次に、ファイルをサーバーにアップロードします。 次に、各コンポーネントについて簡単に紹介します。 upload.vue はクリックしてアップロードするロジックをカプセル化していますが、プログレスバーは作成されていません。プログレスバーは、パーセントをパラメータとして後で改善できます。uploadFormDialog.vue は親ボックス、つまりアップロードボタンをクリックした後に表示されるダイアログボックスです。このコンポーネントでは、ページのレイアウト、ドラッグアンドドロップアップロードなどのロジックを完成させる必要があります。 このカプセル化の目的は、コードの保守を容易にすることです。 upload.vue クリックしてコンポーネントをアップロードします <テンプレート> <!--upload.vue クリックしてコンポーネントをアップロードします--> <div class="ファイルセレクタ"> <z-btn class="セレクターbtn" color="プライマリ" @click="ハンドルアップクリック"> ファイルを選択</z-btn> <入力 ref="入力" class="ファイルセレクタ入力" タイプ="ファイル" :multiple="複数" :accept="受け入れる" @change="handleFiles" /> </div> </テンプレート> <スクリプト> 'lodash/function' から {debounce} をインポートします。 エクスポートデフォルト{ データ() { 戻る { 受け入れる: '.jpg、.jpeg、.png、.gif'、 複数: 偽、 list: [], // 選択されたファイルオブジェクト uploadFinished: true, // アップロードステータス startIndex: 0, // アップロード開始インデックス(ファイルの追加に使用) maxSize: 10 * 1024 * 1024, // 10M(バイト単位のサイズ) // ソース: this.$axios.CancelToken.source(), // axios はリクエストをキャンセルします}; }, メソッド: { // リセット reset() { このリスト = []; this.source.cancel(); this.startIndex = 0; this.uploadFinished = true; this.$refs.input && (this.$refs.input.value = null); }, // アップロード関数を呼び出す handleUpClick: debounce(function () { // ここでアップロードステータスを維持し、アップロード処理中はアップロードボタンを無効にすることができます // if (!this.uploadFinished) this.$message.info('前のファイルは上書きされます~'); this.$refs.input.click(); }, 300), ハンドルファイル(e) { const ファイル = e?.target?.files; this.readFiles(ファイル); }, // アップロードする前にファイルをオブジェクトに処理する readFiles(files) { if (!files || files.length <= 0) { 戻る; } for (const ファイル) { 定数 url = window.URL.createObjectURL(ファイル); 定数オブジェクト = { title: file.name.replace(/(.*\/)*([^.]+).*/ig, '$2'), // ファイルサフィックス url を削除します。 ファイル、 ファイルタイプ: ファイルタイプ、 status: 0, // ステータス -> 0 待機中、1 完了、2 アップロード中、3 アップロード失敗 percent: 0, // アップロードの進行状況}; // アップロードするファイルを保存するために、事前にデータ内にリストを定義します。this.list.unshift(obj); this.$emit('fileList', this.list); } // 最初はデータの startIndex を 0 に定義し、アップロードが完了したらアップロードされたファイルを追加するために更新します // this.startUpload(this.startIndex); }, } }; </スクリプト> <スタイル lang="scss"> .ファイルセレクター{ .セレクターボタン{ &:ホバー{ 背景色: rgba($color: #2976e6, $alpha: 0.8); 遷移: 背景 180 ミリ秒; } } &-入力{ 表示: なし; } } </スタイル> uploadFormDialog.vue アップロードダイアログボックス <テンプレート> <!-- アップロードダイアログ --> <フォームダイアログ v-model="$attrs.value" :title="タイトル" 持続的 :loading="読み込み中" 最大幅="600px" 最小高さ='400px' @cancel="キャンセル処理" @confirm="handleSubmit" > <div クラス="d-flex flex-row justify-space-between"> <z-form style='幅: 260px; 高さ: 100%;'> <form-item label="画像名" 必須> <z-テキストフィールド v-model="フォームデータ名" 概説 :rules="ルール" :disabled='無効' placeholder="画像の名前を入力してください" > </z-テキストフィールド> </フォーム項目> <form-item label="説明" 必須> <z-テキストエリア v-model="フォームデータの説明" 概説 :disabled='無効' placeholder="説明を入力してください" スタイル="resize: none;" > </z-テキストエリア> </フォーム項目> </z-フォーム> <div ref="pickerArea" class="rightBox"> <div class="uploadInputs d-flex flex-column justify-center align-center" :class="[ ドラッグ ? 'ドラッグ' : '']"> <div ref="uploadBg" class="uploadBg my-2"></div> <アップロード ref="アップロードボタン" @fileList='ファイルリスト' </アップロード> <div class="tip mt-2">アップロードボタンをクリックするか、ファイルをボックスにドラッグしてアップロードします</div> <div class="tinyTip ">10M 以下のファイルを選択してください</div> </div> </div> </div> </フォームダイアログ> </テンプレート> <スクリプト> 'lodash/function' から {debounce} をインポートします。 './upload' からアップロードをインポートします。 '@/wv-main-admin/apis/image' から {uploadImage} をインポートします。 エクスポートデフォルト{ コンポーネント: アップロード }, プロパティ: ['dialogData'], データ() { 戻る { ダイアログフラグ: ''、 タイトル: 「画像の追加/編集」 読み込み中: false、 フォームデータ: { 名前: ''、 説明: '' }, 無効: false、 ルール: [v => !!v || '必須'], データ: {}、 dragging: true, //ドラッグするかどうかbindDrop: false, ファイル情報: {}, }; }, マウント() { }, 破棄する前に() { // コンポーネントが破棄される前にドラッグイベントをアンバインドする try { const dropbox = this.$refs.pickerArea; dropbox.removeEventListener('drop', this.handleDrop); dropbox.removeEventListener('dragleave', this.handleDragLeave); dropbox.removeEventListener('dragover', this.handleDragOver); this.bindDrop = false; } catch (e) { console.log(e, '=======コンポーネントが破棄される前にドラッグ イベントをバインド解除する際に例外が発生します'); } }, メソッド: { //キャンセル handleCancle() { // 現在のポップアップ ボックスを閉じます this.$emit('input', false); // コンポーネントを強制的に更新します。this.$forceUpdate(); }, handleSubmit: デバウンス(function() { // 1 つのファイルをアップロードします const flag = this.checkMustsItem(); if (フラグ) { アップロードを開始します。 //アップロードが完了したら、コンポーネントを強制的に更新します。$forceUpdate(); } }, 300), //サブコンポーネントの値をリッスンする fileList(data) { this.fileInfo = データ[0]; this.formData.name = this.fileInfo.title; 定数 uploadBg = this.$refs.uploadBg; //背景画像を変更する uploadBg.style.backgroundImage = `url(${this.fileInfo.url})`; }, バインドイベント() { const dropbox = this.$refs.pickerArea; // 重複したバインディングイベントを防ぐには、データ内でbindDropをfalseに初期化する必要があります。 if (!dropbox || this.bindDrop) { return; } // ドラッグ イベントをバインドし、コンポーネントが破棄されたときにバインドを解除します。dropbox.addEventListener('drop', this.handleDrop, false); dropbox.addEventListener('dragleave', this.handleDragLeave); dropbox.addEventListener('dragover', this.handleDragOver); this.bindDrop = true; }, // アップロードエリアにドラッグ handleDragOver(e) { e.stopPropagation(); e.preventDefault(); this.dragging = true; }, // アップロードエリアを離れる handleDragLeave(e) { e.stopPropagation(); e.preventDefault(); this.dragging = false; }, //ドラッグ終了 handleDrop(e) { e.stopPropagation(); e.preventDefault(); this.dragging = false; const ファイル = e.dataTransfer.files; // <upload/> コンポーネントのアップロード関数を呼び出します。 this.$refs.uploadBtn && this.$refs.uploadBtn.readFiles(files); }, // アップロードする前にファイルを検証する必要があります checkFile(index) { const ファイル = this.list[インデックス]; // ファイルが存在しない場合は、すべてのファイルがアップロードされます if (!file) { //アップロードが完了したら、親コンポーネントに成功イベントをスローします。this.uploadFinished = true; this.$emit('success', this.list); // 変更イベントが正常にトリガーされるように、アップロード コントロールの値をクリアします。this.$refs.input.value = null; this.startIndex = index > 1 ? index - 1 : 0; false を返します。 } // アップロードされたかどうかを確認します if (`${file.status}` === '1') { this.startUpload(++インデックス); false を返します。 } // ファイルサイズをチェックします if (this.maxSize && file.file && file.file.size >= this.maxSize) { this.startUpload(++インデックス); false を返します。 } true を返します。 }, チェック必須項目() { if (!this.fileInfo.file) { this.$message.warning('ファイルをアップロードしてください!'); false を返します。 } if (!this.formData.name) { this.$message.warning('ファイル名を入力してください!'); false を返します。 } if (!this.formData.description) { this.$message.warning('ファイルの説明を入力してください!'); false を返します。 } true を返します。 }, // 単一のファイルをアップロードする startUpload() { this.loading = true; 定数パラメータ = { タイプ: '画像' }; this.$set(params, 'file', this.fileInfo.file); this.$set(params, 'name', this.formData.name); this.$set(params, 'description', this.formData.description); アップロード画像(パラメータ) .then(res => { this.loading = false; (res.code === 0)の場合{ this.$message.success('アップロードに成功しました~'); this.$emit('refreshList', false); this.$emit('input', false); } }) .catch(() => { this.loading = false; }); // this.$axios({ // url: this.url, // アップロードインターフェース、props によって渡される // メソッド: 'post', // データ、 // withCredentials: true、 // cancelToken: this.source.token、 // インターフェースリクエストをキャンセルするために使用されます // // 進行状況バー // onUploadProgress: e => { // if (fileObj.status === 1) { return; } // アップロード済み // // 最大値は 99% に制限されます // 定数 p = parseInt((e.loaded / e.total) * 99); // if (e.total) { // fileObj.status = 2; // アップロード中 // fileObj.percent = p; // アップロードの進行状況を更新 // } else { // fileObj.status = 3; // アップロードに失敗しました // } // }, // }) // .then(レスポンス => { // if (`${response.code}` === '200') { // ファイルObj.ステータス = 1; // ファイルオブジェクトパーセント = 100; // } それ以外 { // ファイルObj.ステータス = 3; // } // }) // .catch(e => { // console.log(e, '====エラー'); // ファイルObj.ステータス = 3; // }) // .finally(e => { // console.log(e, '====エラー'); // this.startUpload(++index); // }); // アップロードが完了しました}, }, }; </スクリプト> <style lang='scss' スコープ> .rightBox{ 幅: 260ピクセル; 高さ: 250px; 境界線: 1px 実線 #ccc; 上マージン: 18px; .uploadBg { 幅: 150ピクセル; 高さ: 125px; 背景: url("../../../../assets/upload.png") 繰り返しなし 中央 中央; 背景サイズ: 含む; } 。ヒント { フォントサイズ: 13px; 色: rgba(0, 0, 0, 0.87); } .tinyTip { フォントサイズ: 12px; 色: #8e8f9e; } } </スタイル> 注: 上記のコードは、当社独自のカプセル化されたコンポーネント ライブラリと、当社でカプセル化したいくつかのメソッドを使用しています。特定のシナリオに応じて、関連する変更を行ってください。 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
>>: Nginx/Httpd ロードバランシング Tomcat 設定チュートリアル
プロジェクト要件では、アップロードされたドキュメントの前処理が必要です。ユーザーが doc 形式でド...
コンテナをソートするためにdepends_onを使用しても、コンテナ間の依存関係の問題は完全には解決...
質問: コンピュータを再起動した後、docker の mysql コンテナを再起動できません。原因が...
序文前回の記事では、主にグリッドシステムの基本原理を学び、簡単なケースを通してその原理を実践しました...
一般的な書き方は次のとおりです。 XML/HTML コードコンテンツをクリップボードにコピー<...
テーブル名を変更したり、テーブル フィールドを変更したりする必要がある場合は、 MySQL ALTE...
目次1件のレビュー2 水平分割の5つの戦略2.1 ハッシュ2.2 範囲2.3. キー2.4. リスト...
多くの場合、画像をコンテナのサイズに合わせて調整する必要があります。 1. imgタグ方式幅と高さを...
目次1. querySelectorは単一の要素を照会する1. ドキュメントインスタンスの呼び出し2...
設定ファイルを server.xml と content.xml に書き込みます。サーバーを再起動す...
MySQL 8.0.18 では、インデックスが作成されていないフィールドに適用でき、等価値の関連付け...
序文: Vue では、props を使用して、もともと分離されていたコンポーネントを直列に接続するこ...
/etc/docker/daemon.json を編集し、以下を追加します。 { "ストレ...
ステートメント 1: <link rel="shortcut icon" ...
早速ですが、デモ画像をご紹介します。実装されている機能は、左側に凡例、右側にウォーターフォール チャ...