4

I am trying to display 9 different images in a loop using v-for.

But, they are are not showing. If I show it without any loop, it works.

I am extracting the right resource but, still, it won't display.

This is my code:

<img class="list-complete-img" src="../assets/g1.jpg" alt="" /> //This works
<div v-for="item in data.items" :key="item.id">
    <div>
        {{ item.src }} // Just to check if I am printing right
    </div>
    <img class="list-complete-img" :src="item.src" :alt="item.src" /> // This does not work
</div>

Now the result that I am getting is:

This is the snippet I am receiving

This is my data.json:

 "items": [
    { "id": "1", "src": "../assets/g1.jpg", "tags": ["all", "tag1"] },
    { "id": "2", "src": "../assets/g2.png", "tags": ["all", "tag2"] },
    { "id": "3", "src": "../assets/g3.png", "tags": ["all", "tag2"] },
    { "id": "4", "src": "../assets/g4.png", "tags": ["all", "tag1"] },
    { "id": "5", "src": "../assets/g5.png", "tags": ["all", "tag1"] },
    { "id": "6", "src": "../assets/g6.png", "tags": ["all", "tag2"] },
    { "id": "7", "src": "../assets/g7.jpg", "tags": ["all", "tag1"] },
    { "id": "8", "src": "../assets/g8.png", "tags": ["all", "tag2"] },
    { "id": "9", "src": "../assets/g9.png", "tags": ["all", "tag2"] }
  ]

EDIT

So far, I have observed that the problem lies with the src. If I am using an image link, it is working just fine. But, not with a local image(only if I used bunch of local images in a loop and working just fine in single). So, what I can do is put the file directory here. I would recommend if anyone of you can try on your local computer and try to upload images from your file directory in a loop and post it here.

File Directory

Inspect Element as required


SOLVED

It needed this statement exactly: require, the path directory and image name.

<div v-for="item in items" :key="item.id">
    <div>
        {{ item.src }}
    </div>
    <img
        class="list-complete-img"
        :src="require(`../assets/${item.src}`)"
        :alt="item.src"
    />
</div>
Daniel_Knights
  • 7,940
  • 4
  • 21
  • 49
kheman garg
  • 63
  • 1
  • 9

4 Answers4

4

This is issue has to do with the following quote of Evan You, which can be found here:

Because the imagePath is only rendered by Vue at runtime, Webpack has no chance of rewriting it.

Your JavaScript code needs to be like this:

export default {
  name: "App",
  data: function () {
    return {
      items: [
        { id: "1", src: "logo.png", tags: ["all", "tag1"] },
        { id: "2", src: "logo.png", tags: ["all", "tag2"] },
        { id: "3", src: "logo.png", tags: ["all", "tag2"] },
        { id: "4", src: "logo.png", tags: ["all", "tag1"] },
        { id: "5", src: "logo.png", tags: ["all", "tag1"] },
        { id: "6", src: "logo.png", tags: ["all", "tag2"] },
        { id: "7", src: "logo.png", tags: ["all", "tag1"] },
        { id: "8", src: "logo.png", tags: ["all", "tag2"] },
        { id: "9", src: "logo.png", tags: ["all", "tag2"] },
      ],
    };
  },
  methods: {
    getImgUrl: function (imagePath) {
      return require('@/assets/' + imagePath);
    }
  }
};

Afterwards, you need to call your getImgUrl function by passing the filename. Your HTML will be like this:

<div id="app">
  <img class="list-complete-img" src="./assets/logo.png" />
  <div v-for="item in items" :key="item.id">
    <img class="list-complete-img" :src="getImgUrl(item.src)" />
  </div>
</div>

Since I do not have access to your images, I have taken the liberty to use the Vue logo as an image.

In summary, the above problem has to do that when Vue compiles, it takes all the assets and puts them in another folder like the image below:

enter image description here

Follow this pattern and your example will also work. Enjoy!

EDIT: If you want, you can have your static assets placed in the public folder. In that way, you will be able to write static paths for your assets.

vchan
  • 835
  • 2
  • 11
  • 27
  • This has made me come closer to discovering my problem and data.items does not matter since I am using separate data.json file rather than using it in the same file that's why I have written that like this. But I have edited the problem please check because of you guys I know the problem lies with the src. – kheman garg Aug 17 '20 at 12:04
  • @khemangarg I need you to inspect the element when it has been rendered on the browser and post a screenshot? – vchan Aug 17 '20 at 12:07
  • edited and posted – kheman garg Aug 17 '20 at 12:37
  • @khemangarg I have edited my answer to your question. Give it a try and let me know. – vchan Aug 17 '20 at 13:42
1

try this: v-for="(item, i) in items" :key="i"

Ehsan
  • 766
  • 10
  • 17
  • Nope still not working. Problem is not that it doesn't print the correct thing. It does print correctly but problem is it's not displaying the IMG as if I am putting the wrong SRC which is put in single image it's fine. – kheman garg Aug 17 '20 at 06:43
  • write your code on codepen – Ehsan Aug 17 '20 at 06:54
0

To use dynamic images, use require(). Change what you have to this.

<div id="app">
    <div v-for="item in data.items" :key="item.id">
        <img ... :src="require(item.src)" />
    </div>
</div>
Tony
  • 1,414
  • 3
  • 9
  • 22
  • I was hoping that this would work but no still not working with this the page goes all blank. But I have edited the problem please check because of you guys I know the problem lies with the src. – kheman garg Aug 17 '20 at 12:02
  • @khemangarg, please could you post your `data` property with the `items` property? Also, please show me where your data.json is imported. I actually thought `items` was a data property. I will edit my answer. I have replaced `items` with `data.items`. – Tony Aug 17 '20 at 13:28
  • Tony man I have voted you. I had a strong feeling with this one =. You were right about require part. All i needed to is add path directory inside require and not in my data. so the code snippet for this is:
    {{ item.src }}
    – kheman garg Aug 17 '20 at 13:43
  • 1
    I am happy your challenge has been solved, @khemangarg. :) – Tony Aug 17 '20 at 13:46
0

you can use a for loop which may help correct me if I am wrong