2020/10/09
Vue.jsで見た目が綺麗なImage Pickerを作る
概要
こんな感じの、未選択画像をクリックすると画像をローカルから選択できて
選択後にアップロードなどに使えるコントロールをVue.jsを使って簡単に作ってみたいので、その内容のメモになります。
- 画像エリアをクリックすると画像選択ができます
- ローカルから画像をドロップして選択もできます
実装方法
マークアップ
htmlマークアップ部分は以下のような感じになります
ポイントとしては
- 画像の表示用のURLが設定されている場合はimgタグを表示し、そうでない場合は、未設定のアイコンが表示されるようにします。
- 以下の例では、vuetifyのコントロールを使っていますが、普通のhtmlタグ(v-imgの代わりにimgタグを、v-sheetやv-rowなどの代わりにdivタグ)を使っても動くはずです
- また、
input type="file"
のコントロールを設定し、cssで隠れるようにします。(opacity: 0
)
<div
class="image-picker-wrapper"
:style="{ 'max-width': '320px' }"
>
<v-img
v-if="myImageUrl"
max-width="320px"
:src="myImageUrl"
></v-img>
<v-sheet
v-else
color="grey lighten-3"
width="320"
height="164"
tile
>
<v-row justify="center" align="center" class="fill-height">
<v-icon size="82">mdi-image-off</v-icon>
</v-row>
</v-sheet>
<input
class="image-picker"
type="file"
accept="image/*"
@change="myImageChanged"
/>
</div>
<style scoped lang="scss">
.image-picker-wrapper {
position: relative;
input.image-picker {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: block;
width: 100%;
height: 100%;
cursor: pointer;
opacity: 0;
}
}
</style>
また、選択された後のデータの保存は以下の関数を定義しておきます。
これをすることで、画像をローカルPC上で選択した後に、imgタグで表示し、かつそのデータを myImageFile
というフィールドに格納することができます。
export default {
data() {
return {
myImageUrl: '',
myImageFile: null,
}
},
// もし画像ファイルをサイズを取得して最大byte数チェックなどをする場合には、以下を定義しておくと便利です
computed: {
myImageFileSize: {
get() {
this.myImageFile ? this.myImageFile.size : 0
}
},
},
methods: {
myImageChanged(event) {
let imageFile = null
const files = event.target.files
if (files.length > 0) {
imageFile = files[0]
}
if (imageFile == null) {
return
}
const self = this
const reader = new FileReader()
reader.onload = function() {
const imageUrl = reader.result
self.myImageFile = imageFile
self.myImageUrl = imageUrl
}
reader.readAsDataURL(imageFile)
}
}
}
myImageFile
に格納された画像ファイルのデータは以下のようにして、サーバーにアップすると良いでしょう。
アップロード時の処理
const formData = new FormData()
formData.append('my_image_file', this.myImageFile)
await this.$axios.$post('/your-server/file-upload-path', formData).then((data) => { /* 省略 */ }).catch((err) => { /* 省略 */ })
その他参考になる記事
以上です。
関連する記事
Nuxt2からNuxt3への移行とNextJSとNuxt3の比較について
弊社ホームページとブログサイトをNuxt2からNuxt3ベースに移行しました。
Nuxt.jsからNext.jsへのリニューアルを経て思うこと
Nuxt.jsからNext.jsへフルリニューアルしたことで見えてきた個人的なメリットとデメリットを整理します
NuxtJSにEditor.jsを導入
リッチでカスタマイズが自由なテキストエディタであるEditor.jsをNuxtJSのサイトに導入しました。
AOSをNuxtJSのサイトに導入する
スクロールアニメーションを簡単に実装できるAOSというライブラリをNuxtJSベースのサイトに導入しました