13

I want to pass image url to child component but image is not showing.

I tried v-attr, :attr, :src properties.

pages/index.vue

<ThumbNail img-url="assets/img/igsim_intro.png"/>

components/Thumbnail.vue

<!-- Failed to resolve directive: attr -->
<img v-attr="imgUrl" /> 

<!-- 404 Not found: http://localhost:3000/assets/img/pds_main.png -->
<img :src="imgUrl" />

<img :attr="{src: imgUrl}" /> 
<script>
export default {
  name: "ThumbNail",
  props: {
    imgUrl: {
      type: String,
      default: ''
    }
  }
}
</script>

I expect Thumbnail.vue show images as passed url.

kissu
  • 40,416
  • 14
  • 65
  • 133
SooJungChae
  • 219
  • 1
  • 4
  • 16

11 Answers11

29

As the src properties will be replaced by Webpack, you could do require function like this

ChildComponentExample.vue

<templae>
  <div>
    <img :src="imageUrl">
  </div>
</template>

<script>
export default {
  props: {
    imageUrl: {
      type: String,
      default: ''
    }
  }
}
</script>

ParentComponent.vue

<template>
  <ChildComponentExample :image-url="require('~/assets/myimage.png')" />
</template>
Aditya Kresna Permana
  • 11,869
  • 8
  • 42
  • 48
  • 1
    This should be marked as correct answer. Also in my case I just passed an array of objects (each object represent an img) and pass a key with imgSrc and value of require("path/to/img") – ProllyGeek Jun 14 '20 at 21:49
  • This blog post explains how this works: https://blog.lichter.io/posts/dynamic-images-vue-nuxt/ – RockyK Aug 14 '20 at 02:41
3

From this answer by Aditya Kresna Permana

For me, It's not working correctly because :image-url in ParentComponent.vue not the same as props in ChildComponentExample.vue

:image-url="require('~/assets/myimage.png')" change :image-url to :imageUrl (same as in props in ChildComponentExample.vue )

Result: :imageUrl="require('~/assets/myimage.png')"

Example ParentComponent.vue:

<template>
  <div v-for="item in items" :key="item.id>
    <ChildComponent 
      :imageURL="require(`~/assets/${item.imgURL}`)" 
      :title="item.title"
      :descriptions="item.descriptions"
    />
  </div>
</template>

<script>
import ChildComponent from '~/components/ChildComponentExample.vue'

export default {
components:{
  ChildComponent,
},
data() {
    return {
      items: [
        {
          id: 1,
          imgURL: '01-1.webp',
          title: 'Title1',
          descriptions: 'Lorem ipsum',
        },
        {
          id: 2,
          imgURL: '02-1.webp',
          title: 'Title2',
          descriptions: 'Lorem ipsum',
        },
      ],
    }
  }
} 
</script>

Example ChildComponentExample.vue:

<template>
  <div>
    <div>
      <img :src="imageURL" alt="Alt text" />
      <div>
        <h3> {{ title }} </h3>
        <div> {{ descriptions }} </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    imageURL: {
      type: String,
      required: true,
      default: '',
    },
    title: {
      type: String,
      required: true,
      default: 'Title',
    },
    descriptions: {
      type: String,
      required: true,
      default: 'No descriptions',
    },
  },
}
</script>
kissu
  • 40,416
  • 14
  • 65
  • 133
l2D
  • 324
  • 4
  • 8
2

According to https://nuxtjs.org/docs/directory-structure/assets/

<img :src="require(`~/assets/img/${image}.jpg`)" />
Sasha Kos
  • 2,480
  • 2
  • 22
  • 37
1

It is prety simple see the examle on codesandbox. And be sure you use the right path to the image.

parent

<template>
  <Logo :width="350" :image-src="image"/>
<template>
  ....

<script>
import Logo from '~/components/Logo.vue'
  
export default {
  components: {
    Logo
  },
  data() {
    return{
      image:'http://4.bp.blogspot.com/-jjDh65rKHak/Vipmdm4eYtI/AAAAAAAAABU/j9iH8nRP3Ms/s1600/bist%2Bimege.jpg'
    }
  }
}
</script>

child

<template>
  <div>
    <svg :width="width" :height="height" viewBox="0 0 452 342" xmlns="http://www.w3.org/2000/svg">
      <g fill="none" fill-rule="evenodd">
        <path
          d="M139 330l-1-2c-2-4-2-8-1-13H29L189 31l67 121 22-16-67-121c-1-2-9-14-22-14-6 0-15 2-22 15L5 303c-1 3-8 16-2 27 4 6 10 12 24 12h136c-14 0-21-6-24-12z"
          fill="#00C58E"
        />
        <path
          d="M447 304L317 70c-2-2-9-15-22-15-6 0-15 3-22 15l-17 28v54l39-67 129 230h-49a23 23 0 0 1-2 14l-1 1c-6 11-21 12-23 12h76c3 0 17-1 24-12 3-5 5-14-2-26z"
          fill="#108775"
        />
        <path
          d="M376 330v-1l1-2c1-4 2-8 1-12l-4-12-102-178-15-27h-1l-15 27-102 178-4 12a24 24 0 0 0 2 15c4 6 10 12 24 12h190c3 0 18-1 25-12zM256 152l93 163H163l93-163z"
          fill="#2F495E"
          fill-rule="nonzero"
        />
      </g>
    </svg>

    <img :src="imageSrc" />
  </div>
</template>

<script>
export default {
  props: {
    width: {
      type: Number,
      default: 452,
    },
    height: {
      type: Number,
      default: 342,
    },
    imageSrc: {
      type: String,
      required: true,
    },
  },
}
</script>
kissu
  • 40,416
  • 14
  • 65
  • 133
Sabee
  • 1,763
  • 9
  • 19
1

This will work for Nuxt 3 with Vite

<template>
  <img :src="getImageUrl()" :alt="alt">
</template>

<script setup lang="ts">
const props = defineProps({
  img: { type: String, default: 'placeholder.png' },
  alt: { type: String, default: 'Image' }
})

const getImageUrl = () => {
  return new URL(`/assets/images/${props.img}`, import.meta.url)
}
</script>
suchrile
  • 11
  • 2
0
<!-- 404 Not found: http://localhost:3000/assets/img/pds_main.png -->

this indicates this way correct! what wrong is your image path. look if your pds_main.png in the path: /assets/img/

Xufeng He
  • 1
  • 2
0

This is how I will do. I have faced a similar problem and got the solution is that. You have to keep your images in the static folder, not in the assets folder and then just s do this.

In your component thumbnail.vue file.

<template>
    <div class="thumbnail-image">
      <img :src="thumbnail">
    </div>
</template>

<script>
  export default {
  props: {
    thumbnail: String
    }
  }
</script>

Now in your Pages.

Import the component and do this.

<template>
  <thumbnail thumbnail="/images.jpg" />
</template>

<script>
import Thumbnail from '~/components/thumbnail'

export default {
  components: {
    Thumbnail
  }
}
</script>

the path after / automatically goes to the static folder. Remember to put your assets in static folder otherwise, you will get a white blank div.

well, its good to have assets in assets folder but in this situation, you gotta keep those in the static folder. Hope this will solve your problem

kissu
  • 40,416
  • 14
  • 65
  • 133
  • What is static folder and assets folder different? And why assets folder isn't a static folder? – SooJungChae Jun 26 '19 at 04:54
  • 1
    Well assets folder will be processed by webpack when you npm run generate or npm run bulid whereas static folder will not. They both have their pros and cons. you can read more in [https://stackoverflow.com/questions/48808182/nuxt-assets-and-static-folder-when-to-use-which] – Saurabh Chandra Rai Jun 26 '19 at 05:03
  • static folder is not good for images because if you load the SPA with a path (www.spa.com/PATH) it won't be able to find any images because everything in static is '/' but it will search in /PATH. – Paul Dec 22 '20 at 17:43
0

I had a similar scenario when using a <video> component.

I needed to utilize nuxt's assets directory but could not pass ~/assets/video.mp4 down to the child as it was not getting compiled into /_nuxt/assets/video.mp4

To get around the issue I used a <slot> as seen below.
https://v2.vuejs.org/v2/guide/components-slots.html

Then I could either pass a String as the src or a generated asset path.

Following this example you could probably use a <Picture> element to achieve the same result with images.

Child Component

<template>
  <video>
    <slot>
      <source :src="src" />
    </slot>
  </video>
</template>

<script>
export default {
  name: 'VideoComponent',
  props: {
    src: String
  }
}
</script>

Parent Component

<template>
  <VideoComponent src="video-1.mp4" />

  <VideoComponent>
    <source src="~/assets/video.mp4" />
  </VideoComponent>
</template>

<script>
export default {
  props: {
    src: String
  }
}
</script>
tony19
  • 125,647
  • 18
  • 229
  • 307
minlare
  • 2,454
  • 25
  • 46
0

when you have different ports LIKE http:127.0.0.1:8000 (LARAVEL)

data: () =>({ img: process.env.baseUrl, }),

<img :src="img + product.image" :key="product.id">
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 28 '22 at 14:14
0

according to Nuxt.JS document assets directory structure:

Inside your vue templates, if you need to link to your assets directory use ~/assets/your_image.png with a slash before assets. Nuxt.JS directory structure

<ThumbNail img-url="~/assets/img/igsim_intro.png" />
0

If possible in your situation, you can move the image to public folder where it won't be compiled but will be available as is, on the path you specify. If you need Nuxt to process your image then answer given by @Aditya Kresna Permana is correct.

Marek Miś
  • 259
  • 2
  • 8