まあ、自分のやろうとしたことが、正攻法じゃなかっただけかもしれないけど。
まずは、一応
OS: macOS High Sierra 10.13.6
ブラウザ: Chrome 77.0.3865.90
vue: 2.6.10
buefy: 0.8.4
vue + buefy でwebサイトを作っていて、画像ファイルのアップロードとプレビューを実装しようと思った。
それ自体は調べれば色々出てくるので難しいものではなかった。(ちょっと疑問は残ったけど1)
だいぶ雑に書くけど
<template>
<div>
<input type="file" @change="changeImage"/></br>
<img :src="image" />
</div>
</template>
<script>
export default {
data:function(){
return {
image:"",
}
},
methods:{
changeImage:function(e){
const file = e.target.files[0]
if(file){
this.image = window.URL.createObjectURL(file)
}
else{
this.image = ""
}
}
}
}
</script>
こんな感じでできる。
(ほんとは、ファイルがないときはimgタグ隠すとか、fileは画像ファイルだけ受け付けるとか色々必要だけど)
ところがこれを
<template>
<div>
<b-input type="file" @change="changeImage"></b-input></br>
<img :src="image" />
</div>
</template>
<script>
export default {
data:function(){
return {
image:"",
}
},
methods:{
changeImage:function(e){
const file = e.target.files[0]
if(file){
this.image = window.URL.createObjectURL(file)
}
else{
this.image = ""
}
}
}
}
</script>
buefyのb-inputに変更したら途端に動かなくなった。
どうもonChangeが発火していないみたい。
原因がはっきりしないのだけど、(というか調べていない)とりあえずなんとかする方法はある。
そもそも、元々動いていたのだから素直にinputを使う。で、bulmaなり素のcssでデザインをなんとかすれば良い。
こっちの方が正攻法のような気がする。
そもそもbuefyにはb-input以外に、アップロード用のコンポーネントb-uploadがある。
(正体は input type="file" っぽいけど)
こっちだとv-modelでfileオブジェクトをバインドできるので、onChangeイベントも要らず算出プロパティでできたりする。
※ちなみにinputでv-modelを使おうとすると、type="file"の場合、vueのエラーになる。b-uploadも最終的にはinputになるのに、何故……?
<template>
<div>
<b-field class="file">
<b-upload v-model="file">
<a class="button is-primary">
<b-icon icon="upload"></b-icon>
<span>Click to upload</span>
</a>
</b-upload>
<span class="file-name" v-if="file">
{{ file.name }}
</span>
</b-field>
<img :src="image" />
</div>
</template>
<script>
export default {
data:function(){
return {
file:null
}
},
computed:{
image:function(){
return this.file ? window.URL.createObjectURL(this.file) : ""
}
}
}
</script>
この記事を書いていて、「あれ? 最終的にinputになるb-uploadがv-model使えるのなら、b-inputのtype="file"でもv-model使えるんじゃね?」って思ってやってみたけどダメだった。
vue側ではエラーにならないけど、バインドされるのがFileオブジェクトではなくファイルパスの文字列だった。
b-uploadはコンポーネントの中で色々よしなに頑張ってくれているんだろうなあ。
個人的には、いかにも「ファイルアップロードです!」みたいな見た目が嫌いではないし、対応としてはどっちでも良いと思うのだけれど、まあ、状況に合わせて対応すれば良いと思う。
みんなonChangeでFileオブジェクト取得してFileReaderでonloadしてreadAsDataURLでimgのsrcに入れてるんだけど、今回やってるみたいにFileオブジェクトからwindow.URL.createObjectURLじゃダメなの? ↩︎
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント