Madogiwa Blog

主に技術系の学習メモに使っていきます。

Vue.jsでpropsを使ってimgタグのsrc属性を設定する方法

Vue.jsを使っていて親要素から子要素へpropsを使ってimgタグのsrc属性を設定する方法で、ハチャメチャにハマってましたが、一応出来たのでやり方をメモしておきます✍

今回やりたかったこと

下記のような親子関係のコンポーネントを作って親コンポーネントとからpropsを使って子コンポーネントfileSrcを渡して、そのままassets配下の画像のURLを設定したかった。

// Skill.vue
<template>
  <div class="skills">
    <Card fileSrc="../asstes/ruby.png" />
  </div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import Card from './Card.vue';

@Component({
  components: { Card },
})
export default class AboutMe extends Vue {
}
</script>
<style lang="scss" scoped>
</style>
// Card.vue
<template>
  <div class="card">
    <div class="card--image">
      <img :src="fileSrc" />
    </div>
  </div>
</template>
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';

@Component
export default class Card extends Vue {
  @Prop() public fileSrc!: string;
}
</script>
<style lang="scss" scoped>
</style>

しかし、上記のやり方だとError in render: "Error: Cannot find module '../asstes/ruby.png'"が発生し、パスの解決が出来ずに画像が表示されなかった😭

またネット上の情報では:src = require(path)とすれば良いといった情報があったが、この対応を行っても同様のエラーが発生し、上手くいかなかった😭

vue-loader-v14.vuejs.org

forum.vuejs.org

解決策

下記のようにloadImg()メソッドを定義し、:src="loadImg()"としたところ解決した👀
ポイントは「require(../assets/${this.fileName})」です、引数ではファイル名だけ渡すようにして、 式展開をおこなってpathを生成してrequireしてあげると上手くいきました(正しい解決方法かどうかはあれですが。。。)💦

// Card.vue
<template>
  <div class="card">
    <div class="card--image">
      <img :src="loadImg()" />
    </div>
  </div>
</template>
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';

@Component
export default class Card extends Vue {
  @Prop() public fileSrc!: string;
  
  public loadImg(): any {
    return require(`../assets/${this.fileName}`);
  }
}
</script>
<style lang="scss" scoped>
</style>

ちょっといろいろ引数を変えてみてみたのですが、謎・・・🤔

return require(`../assets/${this.imgName}`); //OK
return require('../assets/image.png'); // OK
return require(this.imgSrc); // NG

変数を引数に渡してしまうと上手くパスを解決出来ないみたいですね😥