アバターをアップロードするにはVue-Cropperコンポーネントを使用します。参考までに具体的な内容は以下のとおりです エフェクト表示まずは効果を見てみましょう。効果があなたのニーズを満たさない場合は、それを読み取るのに時間を無駄にする必要はありません。 画像をクリックすると 次に、「画像をアップロード」をクリックしてアップロードを完了します。具体的な効果とページレイアウトは次のようになります。 フロントエンドコード使用する前に、vue-cropper の公式ドキュメントを詳しく読むことをお勧めします。詳細に紹介されており、必要に応じて変更できます: リンク もう1つ: element-uiコンポーネントライブラリはプロジェクト全体で使用されます。使用する前にelement-uiをインポートしてください。 解説のためにコードにコメントを追加します。結局、理由を知るには起源を知らなければなりません。 <テンプレート> <div style="height: 800px;"> <el-tabs v-model="activeName" @tab-click="handleClick" class="tabs"> <el-tab-pane label="個人情報" name="first"> </el-tab-pane> <el-tab-pane label="アバターを変更" name="second"> <div class="アバター_ヘッダー"> <span>現在のアバター</span> </div> <div class="アバター_current"> <img :src="現在の画像"> </div> <div class="アバター_select"> <!-- 元の <input type="file"> タグがあまりにも醜いため、ここでこれを行います。どれほど醜いかは、自分で試して確かめてください。そのため、ボタンを使用してトリガー入力を制御し、ファイルを選択します --> <input type="file" ref="uploads" id="uploads" accept="image/png, image/jpeg, image/gif, image/jpg" hidden @change="setImage($event)"> <el-button type="primary" @click="selectAvatar">画像を選択</el-button> <el-button type="success" style="margin-left:100px;" @click="uploadImg('blob')">写真をアップロード</el-button> </div> <div class="cropper_box"> <div class="アバタークロッパー"> <vue-クロッパー ref="クロッパー" :img="オプション.img" :outputSize="オプション.outputSize" :outputType="オプション.outputType" :info="オプション情報" :canScale="オプション.canScale" :autoCrop="オプション.autoCrop" :autoCropWidth="option.autoCropWidth" :autoCropHeight="option.autoCropHeight" :fixed="オプション.fixed" :fixedNumber="オプション.fixedNumber" :full="オプション.full" :fixedBox="オプション.fixedBox" :canMove="オプション.canMove" :canMoveBox="オプション.canMoveBox" :original="オプション.original" :centerBox="オプション.centerBox" :height="オプションの高さ" :infoTrue="オプション.infoTrue" :maxImgSize="オプション.maxImgSize" :enlarge="オプション.enlarge" :mode="オプションモード" @realTime="実時間" @imgLoad="画像読み込み"> </vue-cropper> </div> <div class="show_preview" :style="{'width': previews.w + 'px', 'height': previews.h + 'px', 'overflow': 'hidden', 'マージン': '5px'}"> <div :style="previews.div"> <img :src="option.img" :style="previews.img"> </div> </div> </div> </el-tab-pane> <el-tab-pane label="パスワードの変更" name="third"> </el-tab-pane> </el-tabs> </div> </テンプレート> <スクリプト> 'qs' から qs をインポートします 'vue-cropper' から { VueCropper } をインポートします エクスポートデフォルト{ データ() { 戻る { アクティブ名:'second', currentimg:this.$store.getters.getAvatar, //ここで管理プレビュー用にユーザー情報をVuexに保存します:{}, オプション:{ img:'', //切り抜いた画像のアドレス, outputSize:1, // 切り取られた画像の品質はオプションです (0,1,-1) outputType:'jpeg', // 切り抜かれた画像のフォーマット info:true, // 画像サイズ情報 canScale:true, // ホイールズームを許可するかどうか autoCrop:true, // デフォルトでスクリーンショットフレームを生成するかどうか autoCropWidth:240, autoCropHeight:240, // デフォルトのスクリーンショットフレームサイズ fixed:true, // スクリーンショットフレームの幅と高さの固定比率を有効にするかどうか fixedNumber:[1,1], // スクリーンショットフレームのアスペクト比、 full:false, // 画像を歪みなく元の比率でトリミングします fixedBox:true, // スクリーンショット ボックスのサイズを固定します。変更は許可されません canMove:false, // アップロードした画像を移動できますか? canMoveBox:true, //スクリーンショットボックスをドラッグできるかどうか original:false, //アップロードされた画像は元の比率に従ってレンダリングされる centerBox:false, //スクリーンショットボックスは画像に制限されるか height:true, //デバイスのDPRに従って比例画像を出力するかどうか infoTrue:false, //trueは実際の出力画像の幅と高さを表示し、falseはスクリーンショットボックスの幅と高さを表示するか、 maxImgSize:3000, //画像の最大幅と高さを制限します。enlarge:1, //画像出力比率はスクリーンショットのフレームに応じて倍数になります。mode:'400px 300px' //画像のレンダリング方法} } }, メソッド: { // タブ切り替え呼び出しメソッド、重要ではありません!不要なコードを削除しました handleClick(){ }, //メソッドselectAvatar()を呼び出して画像を選択する{ this.$refs.uploads.click(); }, // 画像を選択するための実際のメソッド。とりあえずこのように名前を付けましょう setImage(e){ ファイルをe.target.files[0]とします。 if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(e.target.value)) { // this.$message.info("画像タイプが正しくありません"); console.log("画像タイプが正しくありません"); false を返します。 } //blob に変換します。blob を使用する目的は、アップロードされた画像をページに表示することです。let reader = new FileReader(); // ファイルが正常に読み込まれた後、onload メソッドがトリガーされます。 reader.onload = (e) => { データを入力します。 // ページに表示するには、URL 形式に変換します if (typeof e.target.result === 'object') { データ = window.URL.createObjectURL(新しいBlob([e.target.result])) }それ以外{ データ = e.target.result } this.option.img = データ //base64に変換 } reader.readAsDataURL(ファイル) }, リアルタイム(データ){ this.previews = データ; }, // 初期化関数 imgLoad(msg){ console.log("ツール初期化関数 ====="+msg); }, // アバターをアップロードするためのメソッドの呼び出し uploadImg(type){ _this = this とします。 if(type === 'blob'){ //スクリーンショットのBLOBデータ型を取得します。this.$refs.cropper.getCropBlob(async (data) => { formData を新しい FormData() にします。 // データをバックエンドに送信します。独自のバックエンド ロジックに従って処理してください。ユーザー名を Vuex に保存し、直接名前を付けることができます。formData.append("username", this.$store.getters.getUsername); formData.append('file',data,this.$store.getters.getUsername+".jpg"); this.axios.post('/updateavatar',formData).then(function(response){ console.log(応答); 応答データコード == 200 の場合 console.log(応答); _this.currentimg = レスポンスデータ.データ; _this.$store.commit('setAvatar',response.data.data); //新しいアバターをVuexに保存します _this.$router.go(0); //ウェブページを更新する} }) }) } } }, コンポーネント:{VueCropper} }; </スクリプト> <スタイルスコープ> .タブ作成{ 位置: 絶対; 右: 80px; 上: 115px; 上マージン: 5px; zインデックス: 999; } .アバターヘッダー{ 幅: 100%; 高さ: 50px; フォントサイズ: 14; 行の高さ: 50px; フォントの太さ: 550; 左パディング: 20px; テキスト配置: 左; } .アバター_current{ 幅: 100%; 高さ: 260px; テキスト配置: 左; } .アバター_現在の画像{ 幅: 240ピクセル; 高さ: 240px; 左マージン: 20px; } .アバター選択{ テキスト配置: 左; } .クロッパーボックス{ テキスト配置: 左; 位置: 相対的; } .アバタークロッパー{ 上マージン: 40px; 高さ: 350ピクセル; 幅: 450ピクセル; 表示: インラインブロック; } .show_preview{ 表示: インラインブロック; 位置: 絶対; 上:30px; 左: 500ピクセル; } </スタイル> バックエンドコード ここではまずバックエンド処理ロジックについて説明します。 1. アバターを取得すると、その画像はクラウド サーバーに保存されます。ここでは、ドライブ D に独自の静的ファイル ディレクトリを設定します (static_root を参照)。 コントローラー層 @レスポンス本文 @PostMapping("/updateavatar") パブリック結果 updateAvatar(@RequestParam("username") String username,@RequestParam("file") MultipartFile file) は IOException をスローします { userService.uploadAvatar(ユーザー名,ファイル) を返します。 } サービス層はimplに直接実装されている // これはインポートされたツールキットであり、pom.xml にインストールする必要があります。 import cn.hutool.core.io.FileUtil; //ポート情報 @Value("${server.port}") プライベート文字列ポート; プライベート静的最終文字列 ip = "http://localhost"; プライベート静的最終文字列static_root = "D:/devplatform_files"; @オーバーライド パブリック結果 uploadAvatar(String username, MultipartFile file) は IOException をスローします { //元のファイルの名前を取得します。String originalFilename = file.getOriginalFilename(); // 文字列 rootFilePath = System.getProperty("user.dir")+"/src/main/resources/files/"+originalFilename; //ファイル パスを取得します。String rootFilePath = static_root + "/avatar/" + originalFilename; // ファイルに保存FileUtil.writeBytes(file.getBytes(),rootFilePath); //画像にアクセスするために使用するURL 文字列 avatar = ip+":"+port+"/avatar/"+originalFilename; 試す{ //アバター情報をデータベースに保存します。userMapper.updateAvatar(avatar,username); // 自己カプセル化された結果結果の戻りクラス return Result.success(200,"アップロード成功",アバター); }catch (例外 e){ System.out.println(e); Result.fail("アップロードに失敗しました"); を返します。 } } マッパー永続層 @マッパー @リポジトリ パブリックインターフェースUserMapper{ 文字列 getAvatarByUsername(文字列 ユーザー名); } mapper.xml ファイル <?xml バージョン="1.0" エンコーディング="UTF-8"?> <!DOCTYPE マッパー PUBLIC "-//mybatis.org//DTD マッパー 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <マッパー名前空間="com.devplatform.mapper.UserMapper"> <update id="updateAvatar"> ユーザーを更新し、アバターを #{avatar} に設定し、ユーザー名を #{username} に設定します。 </更新> </マッパー> Resultクラスのカプセル化について パブリッククラス Result { private int code; //200 は正常、200 以外は異常を示します private String msg; プライベートオブジェクトデータ。 パブリック静的結果成功(オブジェクトデータ){ success(200、"操作成功"、データ) を返します。 } パブリック静的結果成功(文字列メッセージ){ 成功(200,msg,null)を返します。 } パブリック静的結果成功(intコード、文字列メッセージ、オブジェクトデータ){ 結果 r = new Result(); r.setCode(コード); r.setData(データ); r.setMsg(メッセージ); r を返します。 } パブリック静的結果失敗(文字列メッセージ){ 失敗(400, メッセージ, null)を返します。 } パブリック静的結果失敗(文字列メッセージ、オブジェクトデータ){ 失敗(400, メッセージ, データ)を返します。 } パブリック静的結果失敗(intコード、文字列メッセージ、オブジェクトデータ){ 結果 r = new Result(); r.setCode(コード); r.setData(データ); r.setMsg(メッセージ); r を返します。 } public int getCode() {戻りコード;} パブリック void setCode(int code) {this.code = code;} パブリック文字列 getMsg() {return msg;} パブリック void setMsg(String msg) {this.msg = msg;} public Object getData() {データを返します。} パブリック void setData(オブジェクト データ) {this.data = data;} } イメージがクラウド サーバーに保存されると、URL を介して直接アクセスできるようになります。ここでは、この効果をローカルで示します。この効果が達成された場合にのみ、フロント エンドは img タグ内のイメージにアクセスできます。 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: docker compose の記述ルールについての簡単な説明
>>: Workermanはmysql接続プールのサンプルコードを書きます
序文最近のプロジェクトでは、大量のデータを保存する必要があり、このデータには有効期限があります。クエ...
1. <select style="width:195px" name=&...
目次開発環境用のDocker-ceをインストールする開発環境用のDocker-composeをインス...
MySQL を使用してデータベースをクエリし、左結合を実行すると、関連付けられたフィールドの一部に...
Fuser コマンドとは何ですか? fuser コマンドは、特定のファイル、ディレクトリ、またはソケ...
この記事では、Ubuntu 18.04でのVMware Toolsのインストールと設定について記録し...
テーブル構造を設計する場合、数値型は最も一般的な型の 1 つですが、数値型をうまく使用するのは想像す...
目次React Fiberとは何ですか?なぜReact Fiberなのか? React Fiberは...
データベースデータをエクスポートします:まずcmdを開いてMySQLのbinフォルダに入ります1. ...
生活の中で、インターネットはどこにでもあります。インターネットを通じてゲームをしたり、テレビ番組を見...
<本文> <div id="ルート"> <フォー...
目次1. fill() 構文2. fill() の使用3. まとめ序文:配列の初期化方法についてはよ...
この記事では、タブ切り替え機能を実装するためのJavaScriptの具体的なコードを参考までに共有し...
Linux はオープン システムです。インターネット上には、既成のプログラムやツールが多数存在します...
始める前に、process.env.NODE_ENV にはデフォルトで開発と本番の 2 つの状態しか...