概要
Vue-Nativeアプリ上で選択した画像を、multipart/form-data形式でAPIにリクエストするまでをまとめたいと思います。
実践
画像ファイルを選択
vue.js
async pickImage() {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
quality: 1,
})
store.dispatch("image/selectedImage", result)
}
開発支援サービスのExpo.ioを使用しているため、expo-image-picker
で画像を取り扱います。オプションは公式リファレンス参照。
https://docs.expo.io/versions/latest/sdk/imagepicker/
返り値(result)
Object {
"cancelled": false,
"height": 750,
"type": "image",
"uri": "file://~~~~.jpg",
"width": 748,
}
プレビュー表示
<image
class="image-cover"
:source="{uri: image}"
/>
プレビュー表示する場合は、上記の表記方法でimage
は取得した返り値をvuexで状態管理されたstateにcomputedで監視させて呼び出します。画像ファイルはアプリの起動中に一時的にキャッシュされているので、そのuriで読み込みます。
APIに送信
async saveImage ({state, rootState, dispatch}) {
const data = new FormData();
let extention = state.selectedImage.uri.split(".")[1]
var mineType = await dispatch('mineType', extention)
data.append('image',
{
uri: state.selectedImage.uri,
name: String(rootState.auth.id) + '-image.' + extention,
type: mineType
}
)
var config = {
method: 'post',
url: baseApiUrl + '/users/'+ String(rootState.auth.user.id) + '/image',
headers: {
Accept: "application/json",
"Content-Type": "multipart/form-data",
},
data: data,
};
return axios(config)
},
mineType ({}, extention) {
let allow = {"png":"image/png","pdf":"image/gif","jpeg":"image/jpeg", "jpg":"image/jpg"};
if (allow[extention] !== undefined){
return allow[extention]
}
else {
return undefined
}
}
FormDataには上記の形式でアペンドします。postする際は、ヘッダーオプションにAccept
が必要なので注意が必要です。
参考資料