Vue.js dynamic images not working

I have a case where in my Vue.js with webpack web app, I need to display dynamic images. I want to show img where file name of images are stored in a variable. That variable is a computed property which is returning a Vuex store variable, which is being populated asynchronously on beforeMount.

<div class="col-lg-2" v-for="pic in pics">
   <img v-bind:src="'../assets/' + pic + '.png'" v-bind:alt="pic">
</div>

However it works perfectly when I just do:

<img src="../assets/dog.png" alt="dog">

My case is similar to this fiddle, but here it works with img URL, but in mine with actual file paths, it does not work.

What should be correct way to do it?


I got this working by following code

  getImgUrl(pet) {
    var images = require.context('../assets/', false, /\.png$/)
    return images('./' + pet + ".png")
  }

and in HTML:

<div class="col-lg-2" v-for="pic in pics">
   <img :src="getImgUrl(pic)" v-bind:alt="pic">
</div>

But not sure why my earlier approach did not work.


Here is a shorthand that webpack will use so you don't have to use require.context.

HTML:

<div class="col-lg-2" v-for="pic in pics">
    <img :src="getImgUrl(pic)" v-bind:alt="pic">
</div>

Vue Method:

getImgUrl(pic) {
    return require('../assets/'+pic)
}

And I find that the first 2 paragraphs in here explain why this works? well.

Please note that it's a good idea to put your pet pictures inside a subdirectory, instead of lobbing it in with all your other image assets. Like so: ./assets/pets/


You can try the require function. like this:

<img :src="require(`@/xxx/${name}.png`)" alt class="icon" />

The @ symbol points to the src directory.

source: Vue URL transfrom rules


There is another way of doing it by adding your image files to public folder instead of assets and access those as static images.

<img :src="'/img/' + pic + '.png'" v-bind:alt="pic" >

This is where you need to put your static images:

enter image description here


Your best bet is to just use a simple method to build the correct string for the image at the given index:

methods: {
  getPic(index) {
    return '../assets/' + this.pics[index] + '.png';
  }
}

then do the following inside your v-for:

<div class="col-lg-2" v-for="(pic, index) in pics">
   <img :src="getPic(index)" v-bind:alt="pic">
</div>

Here's the JSFiddle (obviously the images don't show, so I've put the image src next to the image):

https://jsfiddle.net/q2rzssxr/