目次
基本的においらは、Vue.jsのCompositionAPIを使いまふ。
<script setup>
********
</script>
<template>
********
</template>
こんな感じの。
Pythonの表記に近いので。
この場合のフロントエンドのコードを紹介しまふ
(‘ω’)ノ
最終コードはこちら
https://github.com/supplepentan/penta_sample_fastapi_vue
最終的には下記の様な構成になりまふ。
ブラウザ表示はこんな感じになりまふ(右側が殺風景でふが、おきになさらず)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
<script setup lang="ts"> import axios, { AxiosResponse } from "axios"; import { ref } from "vue"; interface Props { buckendUrl: string } const props = defineProps<Props>(); const file = ref(); const previewImage = ref(); const fileSelected = (event: any): void => { file.value = event.target.files[0]; const reader = new FileReader(); reader.onload = () => { previewImage.value = reader.result; }; reader.readAsDataURL(event.target.files[0]); }; const fileUpload = (): void => { console.log(props.buckendUrl); const formData = new FormData(); formData.append("file", file.value); axios .post(props.buckendUrl, formData, { responseType: "blob", }) .then((response: AxiosResponse<any, any>) => { let mineType: string | undefined = response.headers["content-type"]; if (mineType === "image/jpeg" | mineType === "image/png") { console.log(response.headers["content-type"]); const blob = new Blob([response.data], { type: mineType }); let url: string = URL.createObjectURL(blob); const a: HTMLAnchorElement = document.createElement("a"); document.body.appendChild(a); a.download = "returnFile.".concat(mineType.slice(-3)); a.href = url; a.click(); } }) .catch(error => console.log(error)); }; </script> <template> <div> <div class="p-2"> <label class="px-4 py-2 bg-transparent border-blue-500 rounded cursor-pointer bg-sky-200 ring-2 hover:bg-blue-300 hover:text-white hover:border-transparent"> Select File ! <input class="hidden" type="file" v-on:change="fileSelected" /> </label> <button v-on:click="fileUpload" class="px-4 py-2 font-semibold text-blue-700 bg-transparent bg-blue-100 border-blue-500 rounded ring-2 hover:bg-blue-300 hover:text-white hover:border-transparent"> Make It ! </button> </div> <div class="grid grid-cols-2"> <div> <img v-bind:src="previewImage" class="img-fluid" alt="" /> </div> <div v-if="file" class="m-2 p-2 border rounded-lg border-slate-400"> <p>Name: {{file.name}}</p> <p>Size: {{file.size}}</p> <p>Type: {{file.type}}</p> </div> </div> </div> </template> |
基本的に画像系のAIで遊ぶので、
axiosを使って、画像ファイルをバックエンドのpythonにpostして、
AI処理した画像のreturnを取得しまふ。
インストールコマンド
1 |
npm install axios |
①Composition API とTypescriptを使う
1 |
<script setup lang="ts"> |
②axiosとその型をインポート。vueからリアクティブに使用する『ref』をインポートしまふ。
1 2 |
import axios, { AxiosResponse } from "axios"; import { ref } from "vue"; |
③親コンポネートの『AreaMain.vue』から、バックエンドのPost先アドレス(backendUrl)の設定。
1 2 3 4 |
interface Props { backendUrl: string } const props = defineProps<Props>(); |
④『file』は、バックエンドにpostする画像を保持します。
『previesImage』は、post画像選択時のプレビューを保持しまふ。
両方とも『ref』に設定してまふ。
1 2 |
const file = ref(); const previewImage = ref(); |
⑤postする画像選択するコードでふ。
<template>の『<input class=”hidden” type=”file” v-on:change=”fileSelected” />』に対応してまふ。
1 2 3 4 5 6 7 8 |
const fileSelected = (event: any): void => { file.value = event.target.files[0]; const reader = new FileReader(); reader.onload = () => { previewImage.value = reader.result; }; reader.readAsDataURL(event.target.files[0]); }; |
⑥バックエンドにpostするコードでふ。バックエンドで処理した画像をダウンロードしまふ。
<template>の『<button v-on:click=”fileUpload”…』に対応してまふ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
const fileUpload = (): void => { console.log(props.buckendUrl); const formData = new FormData(); formData.append("file", file.value); axios .post(props.buckendUrl, formData, { responseType: "blob", }) .then((response: AxiosResponse<any, any>) => { let mineType: string | undefined = response.headers["content-type"]; if (mineType === "image/jpeg" | mineType === "image/png") { console.log(response.headers["content-type"]); const blob = new Blob([response.data], { type: mineType }); let url: string = URL.createObjectURL(blob); const a: HTMLAnchorElement = document.createElement("a"); document.body.appendChild(a); a.download = "returnFile.".concat(mineType.slice(-3)); a.href = url; a.click(); } }) .catch(error => console.log(error)); }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<template> <div> <div class="p-2"> <label class="px-4 py-2 bg-transparent border-blue-500 rounded cursor-pointer bg-sky-200 ring-2 hover:bg-blue-300 hover:text-white hover:border-transparent"> Select File ! <input class="hidden" type="file" v-on:change="fileSelected" /> </label> <button v-on:click="fileUpload" class="px-4 py-2 font-semibold text-blue-700 bg-transparent bg-blue-100 border-blue-500 rounded ring-2 hover:bg-blue-300 hover:text-white hover:border-transparent"> Make It ! </button> </div> <div class="grid grid-cols-2"> <div> <img v-bind:src="previewImage" class="img-fluid" alt="" /> </div> <div v-if="file" class="m-2 p-2 border rounded-lg border-slate-400"> <p>Name: {{file.name}}</p> <p>Size: {{file.size}}</p> <p>Type: {{file.type}}</p> </div> </div> </div> </template> |
起動コマンド
1 |
npm run dev |
“http://127.0.0.1:5173″にブラウザからアクセスしまふ。
『CTRL』キーを押しながらマウスでクリックでも開けまふ。
ビルドコマンドで『dist』フォルダに出力されまふ。
1 |
npm run build |
後に、ビルドしたファイルをバックエンドのFastAPIに使いまふ。