ryoのぼやき

技術についての学習内容のまとめです。

【Vue.js】なぜかimgが表示されない時の解決法とその理由

この記事の内容

Vueのプロジェクトで、画像を表示しようとした時に、
なぜか画像ファイルが読み込めず、表示がされないことがあると思います。
そのような問題が起こる理由と解決策を書こうと思います。


vue-cliにおけるsrcの読み込みについて

画像が表示されない問題が起こるのは、
主にvue-cliで作成したプロジェクトが多いと思います。
なのでまず、vue-cliにおけるsrcの読み込みについて簡単に説明します。

vue-cliで作成されたプロジェクトでは、画像ファイルを読み込む時に、
file-loaderurl-loaderを使います。(webpackがそのように設定されます)

file-loaderはファイルをpublicな場所に保存するのに使われ、
url-loaderは画像ファイルをbase64エンコードして出力するのに使われるものです。
(他の役割については、ここでは割愛)

つまり、内部的には

<img src="@/assets/sample.png">


createElement('img', { attrs: { src: require('@/assets/samplge.png')}})


<img src="data:image/png;base64, 44GK5YmN44KC54mp5aW944GN44Gg44Gqdw==">



このようにコンパイルされるわけです。

[参考]

HTML and Static Assets | Vue CLI


https://blanche-toile.com/tools/image-to-base64


v-bindによって画像のパスを読み込もうとする場合

Vueを使う以上、v-bindで画像ファイルのパスを読み込みたいケースは多いです。
そして、画像が表示されない問題が起こるのは、このケースの時です。


<template>
  <img v-bind:src="imgPath">
</template>

<script>
  export default {
    data(){
      return {
        imgPath: '@/assets/sample.png'
      }
    }
  }
</script>



このようにv-bindでURLを読み込む場合、
パスはそのまま文字列として出力されます。

<img src="@/assets/sample.png>"


しかし、コンパイル後には/assetsフォルダはないので、
/assetsにある画像ファイルを読み込もうとしても見つけられず、
表示もされないというわけです。


解決法

require()を使う

require()を使い画像をモジュールとして読み込むようにしてあげます。

<script>
  export default {
    data(){
      return {
        imgPath: require('@/assets/sample.png')
      }
    }
  }
</script>


publicフォルダに置く

publicフォルダはwebpackに読み込まれることなく、そのままコピーされます。
つまり、コンパイル後もそのままpublicフォルダが残るので、
パスをそのまま指定しても問題なく画像が読み込めます。


まとめ

画像の読み込みに関しては、vueについてというよりは、
webpackやloaderの仕組みが関係していました。

このあたりは、まだ理解が甘い部分が多いので
積極的に調べて行けたらいいなと思いました。