How to pass dynamic image url in nuxt project

Viewed 22549

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.

8 Answers

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>

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>

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>
<!-- 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/

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

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>

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">
Related