Static image src in Vue.js template
JavascriptWebpackvue.jsJavascript 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:
- In
vue-2
if you don't like to keep your files instatic
folder (relevant info), or - In
vue-2
&vue-cli-3
if you don't like to keep your files inpublic
folder (static
folder is renamed topublic
):
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" />
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