2017/10/12

[Vue.js]imgタグのsrcをバインドして404NotFoundになったときの対処法

Atomic Designの原則を取り入れ開発しており、イメージ用コンポーネントを作っていた。そして親コンポーネントから子コンポーネントに画像ファイルのパスを渡し、動的に画像を表示させたかったのだが、imgタグのsrcに画像ファイルのパスをバインドすると「404 (NotFound)」というエラーになってしまった。

Vue.jsのGitHub上にあるIssueの内容も古く(Vue1.x系)対応できなかったが、いろいろ試したら解消できた。

そこで、対処法をまとめる。

やりたかったこと


※ 以下の内容はvue-cliでScaffoldingしたテンプレートを使っていることを前提とする
<!-- Child.vue -->
<template>
  <div class="image">
    <img :src="imageSrc">
  </div>
</template>

<script>
export default {
  props: {
    imageSrc: {
      type: String,
      isRequired: true
    }
  }
}
</script>
<!-- Parent.vue -->
<div id="app">
  <image-panel imageSrc="../assets/image.png" />
</div>

<script>
import ImagePanel from '@/components/ImagePanel'

export default {
  components: {
    ImagePanel
  }
}
</script>
親コンポーネントからPropsで画像のパスを渡している。子コンポーネントでは<img :src="imageSrc">のようにimgタグのsrcにバインドしている。
この状態だと、http://example.com/assets/image.png 404(Not Found)というエラーになってしまう。

というのも、assetsディレクトリのものは、ビルド後はstaticディレクトリに移されてしまい参照できなくなってしまうからだ。
バインドせずに直接<img src="./assets/image.png">のようにした場合は、vue-loaderがいい感じに変換してくれてるので参照できる。



404 NotFoundになったときの対処法


<!-- Child.vue -->
<template>
  <div class="image">
    <img :src="src">
  </div>
</template>

<script>
export default {
  props: {
    imageSrc: {
      type: String,
      isRequired: true
    }
  },
  data () {
    return {
      src: require(this.imageSrc)
    }
  }
}
</script>

src: require('path/to/image.png')のように読み込むことで、404 NotFoundは解消できる。
今回はPropsで直接画像ファイルのパスを渡しているが、ディレクトリの構成によっては読み込めない場合があるので、URI解決メソッドを用意しておくと良いだろう。

また、今回のようなケースではassetsディレクトリではなくstaticディレクトリに画像を入れておいたほうが良いのかもしれない。



参考サイト





以上

written by @bc_rikko

0 件のコメント :

コメントを投稿