How to import and use image in a Vue single file component?
Asked Answered
P

12

108

I think this should be simple, but I am facing some trouble on how to import and use an image in Vue single file component. Can someone help me how to do this? Here is my code snippet:

<template lang="html">
    <img src="zapierLogo" />
</template>
    
<script>
    import zapierLogo from 'images/zapier_logo.svg'
    
    export default {
    }
</script>
    
<style lang="css">
</style>

I have tried using :src, src="{{ zapierLogo }}", etc. But nothing seems to work. I was not able to find any example too. Any help?

Poliard answered 15/7, 2017 at 9:47 Comment(4)
Just use src='images/zapier_logo.svg' if it is a static svg imageHarrie
Are you getting an error in your console?Conscript
Using an import statement would only work if you are trying to use it as a custom component within the <template> tags and not as a src file for an img tag. You will also need to properly add it to the "component" field of the vue object.Thromboplastic
Not sure if you have tried :src="zapierLogo", without the mustaches.Thromboplastic
B
176

As simple as:

<template>
    <div id="app">
        <img src="./assets/logo.png">
    </div>
</template>
    
<script>
    export default {
    }
</script>
    
<style lang="css">
</style> 

Taken from the project generated by vue cli.

If you want to use your image as a module, do not forget to bind data to your Vuejs component:

<template>
    <div id="app">
        <img :src="image"/>
    </div>
</template>
    
<script>
    import image from "./assets/logo.png"
    
    export default {
        data: function () {
            return {
                image: image
            }
        }
    }
</script>
    
<style lang="css">
</style>

And a shorter version:

<template>
    <div id="app">
        <img :src="require('./assets/logo.png')"/>
    </div>
</template>
    
<script>
    export default {
    }
</script>
    
<style lang="css">
</style> 
Benevolent answered 15/7, 2017 at 10:10 Comment(8)
You might want to also include, image: require('path/to/file') if you wish to include it in data.Faithfaithful
I think we should also mention the use of tilde(~)before the url. In case you are not using require. src="~src/assets/img/me.png"Poliard
:src="require('@/assets/image.png')" Works for me.Blumenthal
how to use it in background-image:url('') ?Hayse
The image as a module way is the only working one for me.Aquanaut
@Hugo Make a computed property to add a background imageSafir
For some reason the first offered solution has never worked for me in any Vue project. I always have to use the import solution, any idea why?Arieariel
@robertfoenix your image path either has to be the relative path our use the src alias @ or ~Preposterous
F
31

It is heavily suggested to make use of webpack when importing pictures from assets and in general for optimisation and pathing purposes

If you wish to load them by webpack you can simply use :src='require('path/to/file')' Make sure you use : otherwise it won't execute the require statement as Javascript.

In typescript you can do almost the exact same operation: :src="require('@/assets/image.png')"

Why the following is generally considered bad practice:

<template>
  <div id="app">
    <img src="./assets/logo.png">
  </div>
</template>

<script>
export default {
}
</script>

<style lang="scss">
</style> 

When building using the Vue cli, webpack is not able to ensure that the assets file will maintain a structure that follows the relative importing. This is due to webpack trying to optimize and chunk items appearing inside of the assets folder. If you wish to use a relative import you should do so from within the static folder and use: <img src="./static/logo.png">

Faithfaithful answered 15/7, 2017 at 10:43 Comment(4)
So <img :src="require('@/assets/image.png')">? This doesn't work for me. It complains about dependency not found.Grazynagreabe
@Grazynagreabe There's a lot of reasons why you might be getting this error, can you expand more or maybe post a question and I can try and debug.Faithfaithful
url-loader allows you to conditionally inline a file as base-64 data URL if they are smaller than a given threshold. This can reduce the amount of HTTP requests for trivial files. If the file is larger than the threshold, it automatically falls back to file-loader. - If you don't use webpack to load your image you won't recieve this benefits or the other mentioned here: vue-loader.vuejs.org/guide/asset-url.html#transform-rules @akauppiFaithfaithful
@akauppi I highly doubt you're using vue.js but not webpack, vue's native development server is webpack and the builder is also webpack, Also you asked if it's still relevant, as per the documentation it's still very relevant thus answering your comment. Next time don't ask a question if you don't want an answer.Faithfaithful
I
15

I came across this issue recently, and i'm using Typescript. If you're using Typescript like I am, then you need to import assets like so:

<img src="@/assets/images/logo.png" alt="">
Islander answered 15/2, 2019 at 2:33 Comment(2)
While this actually does work, you're not taking advantage of webpack in this case.Faithfaithful
I'm not using Typescript but I have to use your solution. Thanks.Phio
T
3

You can also use the root shortcut like so

  <template>
   <div class="container">
    <h1>Recipes</h1>
      <img src="@/assets/burger.jpg" />
   </div>
  </template>

Although this was Nuxt, it should be same with Vue CLI.

Tortfeasor answered 12/3, 2020 at 6:38 Comment(0)
J
3

I'm also facing same problem to display the assets image. Finally this two way work fine for me-

<img src="@/assets/img/bg1.png" />

and

<img :src="require('@/assets/img/bg1.png')" />
Jepum answered 31/12, 2021 at 14:41 Comment(0)
O
2

These both work for me in JavaScript and TypeScript

<img src="@/assets/images/logo.png" alt=""> 

or

 <img src="./assets/images/logo.png" alt="">
Oloroso answered 4/10, 2019 at 12:43 Comment(3)
While this actually does work, you're not taking advantage of webpack in this case. Furthermore this src="./assets/images/logo.png" is discouraged in practice as unlike static you can't ensure how items from the assets directory will be bundled when building.Faithfaithful
@lix what do you mean by advantage of webpack? I assume even the SFC would be compiled through the build pipeline I feel.Poliard
@Poliard When I made this comment using require would convert files to there base64 representation before then using that as the src for loading the image. This is a dynamic resolution that saves size and increases performance of loading an image.Faithfaithful
P
2

I encounter a problem in quasar which is a mobile framework based vue, the tidle syntax ~assets/cover.jpg works in normal component, but not in my dynamic defined component, that is defined by

let c=Vue.component('compName',{...})

finally this work:

    computed: {
      coverUri() {
        return require('../assets/cover.jpg');
      }
    }
<q-img class="coverImg" :src="coverUri" :height="uiBook.coverHeight" spinner-color="white"/>

according to the explain at https://quasar.dev/quasar-cli/handling-assets

In *.vue components, all your templates and CSS are parsed by vue-html-loader and css-loader to look for asset URLs. For example, in <img src="./logo.png"> and background: url(./logo.png), "./logo.png" is a relative asset path and will be resolved by Webpack as a module dependency.

Predigestion answered 20/9, 2020 at 12:41 Comment(0)
I
2

For Vue 3 I had to use

<template>
  <div id="app">
    <img :src="zapierLogo" />
  </div>
</template>

<script>
import zapierLogo from 'images/zapier_logo.svg'


export default {
    ...
    data: function () {
        return {
            zapierLogo
        }
    }
}
</script>

Both src="@/assets/burger.jpg" and src="../assets/burger.jpg" didn't seem to work.

Irksome answered 10/7, 2021 at 11:8 Comment(0)
R
2

..when everything else fails, like in my case as i tried to import a placeholder i used several times in a multipaged Vuelectro-app - but this time inside a sub-subcomponent where none of the suggested solutions worked (as they usually do)..

<template>
    <div id="app">
        <img :src="image"/>
    </div>
</template>

<script>        
    export default {
        data() { return {image: null, ...} },
        methods: {
          solveImage(){
            const path = require('path')
            return path.join(process.cwd(), '/src/assets/img/me.jpg')
          },
          ...
         },
         mounted: {
           this.image = this.solveImage()
           ...
         }
    }
</script>

..should do it.

if it even works better in created-lifecycle-hook or you'd prefer to require path globally and just call

this.image = path.join(...)

in one of the hooks - you should test yourself.

Rudolphrudwik answered 31/10, 2021 at 9:18 Comment(0)
L
1

If you are simply importing an image from the public folder then; you could either import the image as an module

<script setup>
  import orgLogo from '/images/logo.png'
</script>
<img :src="orgLogo" alt="Organization Logo">

or Use the link directly in the src attribute of img

<img src="/images/org.png" alt="Organization Logo">
Logger answered 5/4, 2023 at 7:18 Comment(0)
S
0

in my case i have a base64 image and have to import for parse the mimeType and data from the image

this how the template look like

<template>
<img
          @click="openCardDetail(item)"
          class="thumbnailInfo"
          width="80"
          height="50"   
          :src="getImageToShow(item.stationeryThumbnail)"
        />
</template>

Here i imported the image

import image from '@/assets/noimage.png'

then i instantiated it

data: () => ({
    ...
    image: image,
})

then i used only if there is no data in the item

getImageToShow(item) {
  if(item != null && item?.mimeType !== '' && item?.base64ImageData !== '') {
     return `data:${item?.mimeType};base64,${item.base64ImageData};`
  }
  return `${this.image}`;
}

it solved my problem

Shuttlecock answered 25/8, 2022 at 20:32 Comment(0)
S
0
<script setup>
  import myImg from '@/assets/images/images/my-selfie.png';
</script>

<template>
  <img :src="myImg" />
</template>

you can import the image using it's relative path as shown here 💁🏽

Shiah answered 16/3, 2023 at 13:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.