Techvenience

Technology × Convenience - Vue / React / Next / Nuxt / ChatGPTなどのIT技術がもたらす便利さをお伝えします。最近はChatGPTなどのAI技術を使ってブログを書いています。

【vue-cli】webpackで作成したアプリケーションで、v-bindした画像の読み込みがうまくいかない【v-bind】

【vue-cli】webpackで作成したアプリケーションで、v-bindした画像の読み込みがうまくいかない【v-bind】

f:id:duo-taro100:20160218004611p:plain

v-bindした画像パスが正しく読み込まれない

vue-cli webpackを使ってテンプレートを作成したアプリケーションで、画像パスの指定で迷ったので忘れないように。

直接記述する場合は問題なし

こんな感じのコンポーネントがあったとします。

<template>
  <div id="app">
    <div class="container">
      <div class="main">
        <router-view/>
      </div>
      <!-- menu -->
      <div v-if="isVisibleMenu" class="scroll-menu csr-pointer">
        <transition>
          <img src="./assets/menu-red.png" @click="openModal()">
        </transition>
      </div>
    </div><!-- .container -->
  </div><!-- #app -->
</template>

srcには「./assets/menu-red.png」と指定しました。
これは想定通りの画像が表示されました。

バインドすると上手く表示されない

上記のsrc部分をv-bindして変数を入れてみます。

<template>
  <div id="app">
    <div class="container">
      <div class="main">
        <router-view/>
      </div>
      <!-- menu -->
      <div v-if="isVisibleMenu" class="scroll-menu csr-pointer">
        <transition>
          <img :src="imagePath" @click="openModal()">
        </transition>
      </div>
    </div><!-- .container -->
  </div><!-- #app -->
</template>

<script>
export default {
  name: 'App',
  data : function(){
      return {
        imagePath : './assets/menu-red.png'
      }
  }
}
</script>

imagePathに先程同様に「 ./assets/menu-red.png」を指定し、バインド変数として使いましたが、これだと正しく表示されません。
htmlがどのようになっているか見てみると

<img src="./assets/menu-red.png" @click="openModal()">

となっていました。

vue-loaderのアセットURLハンドリング

答えがここに

アセット URL ハンドリング · vue-loader


コンパイル時に変換されますが、以下のように書くとダメだそうです。

data : function(){
  return {
    imagePath : './assets/menu-red.png'
  }
}

解決方法

require('画像パス')

を使えばいいようです。つまり

data : function(){
  return {
    imagePath : require('./assets/menu-red.png')
  }
}

のようにします。
これで正しく表示されました!