Static image src in Vue.js template

JavascriptWebpackvue.js

Javascript Problem Overview


My Vue component contains some images. I want to do lazy-loading later, so I need to set the src of the images to a small image, first.

<template>
		<div v-for="item in portfolioItems">
			<a href="#{{ item.id }}">
				<img
				    data-original="{{ item.img }}"
					v-bind:src="/static/img/clear.gif"
                    class="lazy" alt="">
			</a>
		</div>
</template>

Gives me a bunch of errors, like:

> [Vue warn]: Invalid expression. Generated function > body: /scope.static/scope.img/scope.clear.gif vue.common.js:1014[Vue

> [Vue warn]: Error when evaluating expression "/static/img/clear.gif": > TypeError: Cannot read property 'call' of undefined (found in > component: )

webpack.config.js:
module.exports = {
    // ...
    build: {
        assetsPublicPath: '/',
        assetsSubDirectory: 'static'
    }
}

Javascript Solutions


Solution 1 - Javascript

This solution is for Vue-2 users:

  1. In vue-2 if you don't like to keep your files in static folder (relevant info), or
  2. In vue-2 & vue-cli-3 if you don't like to keep your files in public folder (static folder is renamed to public):

The simple solution is :)

<img src="@/assets/img/clear.gif" /> // just do this:
<img :src="require(`@/assets/img/clear.gif`)" // or do this:
<img :src="require(`@/assets/img/${imgURL}`)" // if pulling from: data() {return {imgURL: 'clear.gif'}}

If you like to keep your static images in static/assets/img or public/assets/img folder, then just do:

<img src="./assets/img/clear.gif" />
<img src="/assets/img/clear.gif" /> // in some case without dot ./

Solution 2 - Javascript

If you want to bind a string to the src attribute, you should wrap it on single quotes:

<img v-bind:src="'/static/img/clear.gif'">
<!-- or shorthand -->
<img :src="'/static/img/clear.gif'">

IMO you do not need to bind a string, you could use the simple way:

<img src="/static/img/clear.gif">

Check an example about the image preload here: http://codepen.io/pespantelis/pen/RWVZxL

Solution 3 - Javascript

> This is how i solve it.:

      items: [
        { title: 'Dashboard', icon: require('@/assets/icons/sidebar/dashboard.svg') },
        { title: 'Projects',  icon: require('@/assets/icons/sidebar/projects.svg') },
        { title: 'Clients', icon: require('@/assets/icons/sidebar/clients.svg') },
      ],

And on the template part:

<img :src="item.icon" />

See it in action here

Solution 4 - Javascript

@Pantelis answer somehow steered me to a solution for a similar misunderstanding. A message board project I'm working on needs to show an optional image. I was having fits trying to get the src=imagefile to concatenate a fixed path and variable filename string until I saw the quirky use of "''" quotes :-)

<template id="symp-tmpl">
  <div>
    <div v-for="item in items" style="clear: both;">
      <div v-if="(item.imagefile !== '[none]')">
        <img v-bind:src="'/storage/userimages/' + item.imagefile">
      </div>
      sub: <span>@{{ item.subject }}</span>
      <span v-if="(login == item.author)">[edit]</span>
      <br>@{{ item.author }}
      <br>msg: <span>@{{ item.message }}</span>
    </div>
  </div>
</template>

Solution 5 - Javascript

declare new variable that the value contain the path of image

const imgLink = require('../../assets/your-image.png')

then call the variable

export default {
    name: 'onepage',
    data(){
        return{
            img: imgLink,
        }
    }
}

bind that on html, this the example:

<a href="#"><img v-bind:src="img" alt="" class="logo"></a>

hope it will help

Solution 6 - Javascript

You need use just simple code <img alt="img" src="../assets/index.png" />

Do not forgot atribut alt in balise img

Solution 7 - Javascript

I had a similar issue with Vue where I tried to display several images by importing data from a configuration json file and then iterating over the data using v-for.

Even when I put require('../../assets/' + filename) right in the json, the images would never show. I eventually realized that Vue was interpreting my data value as a string, rather than a function. Good thing that javascript supports functions as a return type. So I made this function:

  getImagePath(filename: string) {
    return require('../../assets/' + filename);
  }

I then just called that function from my v-for loop simply passing in the filenames from my config:

<v-list-item :key="place.id" v-for="place in placesOfPower">
  <v-list-item-content class="justify-end">
    <v-img :src="getImagePath(place.image)"
           position="top center"
           height="90"
           width="30vw"/>
  </v-list-item-content>
<v-list-item-content>

Solution 8 - Javascript

I found this thread on my search for a solution to show an image when it exists. I want to show a list of database entries that contain a type property. Each type should have a fitting png file in my vue assets folder. The whole list would break if a new type would be added without adding the image beforehand.

I found "Catch an error on requiring module in node.js" on stack overflow. The answer by Peter Lyons led me to my solution:

<template>
  <v-data-table :items="items">
    <template v-slot:item.type="{ item }">
      <v-img
        v-if="typeImageSource(item.type)"
        :src="typeImageSource(item.type)"
      />
      <template v-else>
        {{ item.type }}
      </template>
    </template>
  </v-data-table>
</template>

<script>
export default {
  data () {
    return {
      // In reality this gets filled from a db:
      items: [
        { id: 1, type: 'abc' },
        { id: 2, type: 'abcd' },
        { id: 3, type: 'efg' },
      ]
    }
  },
  methods: {
    typeImageSource: function (type) {
      let src = ''
      try {
        src = require(`@/assets/types/${('' + type).toLowerCase()}.png`)
      } catch (error) {
        console.warn(`Image for type ${type} could not be found! Please add "${('' + type).toLowerCase()}.png" to the folder "@/assets/types/".\n\n`, error)
        return null
      }
      return src
    },
  },
}
</script>

Solution 9 - Javascript

If you are using nuxt use <img :src="'_nuxt/path_to_your_local_image'" />

if you are using vue first use static src import : <img src="path_to_your_local_image" />

then inspect image element to see what src is rendered to the browser then replace it with a dynamic src

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionreggieView Question on Stackoverflow
Solution 1 - JavascriptSyedView Answer on Stackoverflow
Solution 2 - JavascriptPantelis PeslisView Answer on Stackoverflow
Solution 3 - JavascriptRolandView Answer on Stackoverflow
Solution 4 - JavascriptrickatechView Answer on Stackoverflow
Solution 5 - JavascriptCevin WaysView Answer on Stackoverflow
Solution 6 - JavascriptLamri DjamalView Answer on Stackoverflow
Solution 7 - JavascriptJulian BaltuttisView Answer on Stackoverflow
Solution 8 - JavascriptsebixView Answer on Stackoverflow
Solution 9 - Javascriptfafa.mnzmView Answer on Stackoverflow