0

I know there are a lot of questions and answers about how to use v-bind in v-for to bind to img src ... however, I spent a whole day experimenting in vain. I apologize for a duplicate question, but could anyone help me?

I am using vue@2.6.12 and @vue/cli 4.5.6. I am trying to show multiple images in v-for loop, binding file paths to img src. I have skills data in skills.json, trying to display them in Skills.vue. The code below just shows blank screen.

Any help is appreciated, thank you.

skills.json

[
  {
    "id": 1,
    "name": "C#",
    "logo": "C-Sharp.svg"
  },
  {
    "id": 2,
    "name": "Azure",
    "logo": "azure.svg"
  }
]

Skills.vue

Looking at vue developer tool, I could confirm the data is correctly imported into skills array(but not showing up).

<template>
  <div class="container">
    <div class="items">
      <div class="item" v-for="skill in skills" :key="skill.id">
        <img :src="require(`${logoPath}${skill.logo}`)" />
      </div>
    </div>
  </div>
</template>

<script>
import skillsJson from '../assets/skills.json';

export default {
    data() {
        return {
            skills: skillsJson,
            logoPath: '../assets/img/',
        };
    },
};
</script>

src folder structure

C:.
│  App.vue
│  main.js
├─assets
│  │  skills.json
│  ├─icons
│  ├─img
│  │      azure.svg
│  │      C-Sharp.svg
│  └─scss
├─components
├─router
│      index.js
└─views
        Experience.vue
        HelloWorld.vue
        Home.vue
        Skills.vue
ari
  • 31
  • 9
  • 1
    `require()` for what?? did you tried `:src="logoPath + '/' + skill.logo"` – bill.gates Oct 05 '20 at 12:09
  • Hi Ifaruki. Thank you for your comment. f.ex. according to the link below, it says require is needed if webpack is used. https://stackoverflow.com/questions/55152795/vue-js-data-binding-not-working-for-img-src I just typed "vue create {projectname}", so I assume webpack is used for my project. I tried your source, now it displays images with broken link icons. – ari Oct 05 '20 at 12:15

1 Answers1

2

You need to understand that require() (or import()) is handled by Webpack at build time. Webpack can't execute your code (at build time) and possibly know what the value at runtime will be. Take a look at the docs (it's about import() but require() is almost same)

Simple fix would be to make only part of the path dynamic so Webpack gets at least some hint what file should be made available...

Replace

<img :src="require(`${logoPath}${skill.logo}`)" />

by

<img :src="require(`../assets/img/${skill.logo}`)" />

TLDR

Webpack's require() needs at least some part of the file path to be completely static!

Michal Levý
  • 33,064
  • 4
  • 68
  • 86
  • Hi Levy, thank you for your comment. It is working now! According to the docs, I assume this was causing the issue... "It is not possible to use a fully dynamic import statement, such as import(foo). Because foo could potentially be any path to any file in your system or project. The import() must contain at least some information about where the module is located." Need to learn how Webpack works... Thank you for your help. – ari Oct 05 '20 at 12:26