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?

Answers:

Answer

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/

Answer

Here is Very simple answer. :D

<div class="col-lg-2" v-for="pic in pics">
   <img v-bind:src="`../assets/${pic}.png`" v-bind:alt="pic">
</div>
Answer

You can use try catch block to help with not found images

getProductImage(id) {
          var images = require.context('@/assets/', false, /\.jpg$/)
          let productImage = ''
          try {
            productImage = images(`./product${id}.jpg`)
          } catch (error) {
            productImage = images(`./no_image.jpg`)
          }
          return productImage
},
Answer

well the best and easiest way that worked for me was this of which i was fetching data from an API..

methods: {
       getPic(index) {
    return this.data_response.user_Image_path + index;
  }
 }

the getPic method takes one parameter which is the name of the file and it returns the absolute path of the file maybe from your server with the file name simple...

here is an example of a component where i used this:

<template>
    <div class="view-post">
        <div class="container">
     <div class="form-group">
             <label for=""></label>
             <input type="text" class="form-control" name="" id="" aria-describedby="helpId" placeholder="search here">
             <small id="helpId" class="form-text user-search text-muted">search for a user here</small>
           </div>
           <table class="table table-striped ">
               <thead>
                   <tr>
                       <th>name</th>
                       <th>email</th>
                       <th>age</th>
                       <th>photo</th>
                   </tr>
                   </thead>
                   <tbody>
                       <tr v-bind:key="user_data_get.id"  v-for="user_data_get in data_response.data">
                           <td scope="row">{{ user_data_get.username }}</td>
                           <td>{{ user_data_get.email }}</td>
                           <td>{{ user_data_get.userage }}</td>
                           <td><img :src="getPic(user_data_get.image)"  clas="img_resize" style="height:50px;width:50px;"/></td>
                       </tr>

                   </tbody>
           </table>
        </div>

    </div>
</template>

<script>
import axios from 'axios';
export default {
     name: 'view',
  components: {

  },
  props:["url"],
 data() {
     return {
         data_response:"",
         image_path:"",
     }
 },
 methods: {
       getPic(index) {
    return this.data_response.user_Image_path + index;
  }
 },
 created() {
     const res_data = axios({
    method: 'post',
    url: this.url.link+"/view",
   headers:{
     'Authorization': this.url.headers.Authorization,
     'content-type':this.url.headers.type,
   }
    })
    .then((response)=> {
        //handle success
      this.data_response = response.data;
      this.image_path = this.data_response.user_Image_path;
       console.log(this.data_response.data)
    })
    .catch(function (response) {
        //handle error
        console.log(response);
    });
 },
}
</script>


<style scoped>

</style>
Answer

Try importing image like this , because Webpack should know about its dependancy

    <ul>
              <li v-for="social in socials" 
              v-bind:key="social.socialId"
              >

                <a :href="social.socialWeb" target="_blank">
                  <img class="img-fill" :id="social.socialId" :src="social.socialLink" :alt="social.socialName">
                </a>
              </li>

            </ul>

<script>
        import Image1 from '@/assets/images/social/twitter.svg'
        import Image2 from '@/assets/images/social/facebook.svg'
        import Image3 from '@/assets/images/social/rss.svg'
        export default {
          data(){
            return{
              socials:[{         
                   socialId:1,         
                   socialName: "twitter",
                   socialLink: Image1,
                   socialWeb: "http://twitter.com"
              },
      {
          socialId:2,
          socialName: "facebook",
           socialLink: Image2,
           socialWeb: "http://facebook.com"

      },
      {
          socialId:3,
          socialName: "rss",
           socialLink: Image3,
           socialWeb: "http://rss.com"
      }]

 </script>
Answer

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.

Answer

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

Answer

You can try the require function. like this:

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

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/

Answer

I also hit this problem and it seems that both most upvoted answers work but there is a tiny problem, webpack throws an error into browser console (Error: Cannot find module './undefined' at webpackContextResolve) which is not very nice.

So I've solved it a bit differently. The whole problem with variable inside require statement is that require statement is executed during bundling and variable inside that statement appears only during app execution in browser. So webpack sees required image as undefined either way, as during compilation that variable doesn't exist.

What I did is place random image into require statement and hiding that image in css, so nobody sees it.

// template
<img class="user-image-svg" :class="[this.hidden? 'hidden' : '']" :src="userAvatar" alt />

//js
data() {
  return {
    userAvatar: require('@/assets/avatar1.svg'),
    hidden: true
  }
}

//css
.hidden {display: none}

Image comes as part of information from database via Vuex and is mapped to component as a computed

computed: {
  user() {
    return this.$store.state.auth.user;
  }
}

So once this information is available I swap initial image to the real one

watch: {
  user(userData) {
    this.userAvatar = require(`@/assets/${userData.avatar}`);
    this.hidden = false;
  }
}
Answer

I encountered the same problem. This worked for me by changing '../assets/' to './assets/'.

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

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us Javascript

©2020 All rights reserved.