Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing and binding img src from props in Vue.js

Tags:

image

vue.js

I am trying to display an image with the img tag by using a path from props for the src attribute.

I've tried changing the path with @, using the whole path with src, adding ../assets/ in the component and only passing the file name (orange.png) as props. I always get the default broken image displayed. When inspecting in the browser, the path seems fine. When I display the image directly, I can see that the path is resolved to some different path <img data-v-1212d7a4="" src="/img/orange.7b71a54c.png">.


Edit: Additionally I tried this post Can't dynamically pass relative src path for imgs in Vue.js + webpack , where using <img :src="require(picture_src)" /> is given as an answer. This leads to an error: Error in render: "Error: Cannot find module '../assets/orange.png'"

(Edit2: This answer in the end worked for me in the end as described in my answer post.)
The same error occurs with the similar webpack method using let images = require.context('../assets/', false, /\.png$/) in my script part, as the answer on this post Can't dynamically pass relative src path for imgs in Vue.js + webpack .


I am new to Vue.js, so I don't exactly know what is happening or how to search for this or it might not have anything to do with what I'm originally trying.

I am able to display my image when I pass the path directly, like this

<img src="../assets/orange.png"/>

Now I'd actually like to pass it to my component in the props and then, inside the component, display it reading the path from props.

Component

<template>
  <div>
    <img :src=picture_src />
    <div class="pic_sub">{{pic_desc}}</div>
  </div>
</template>
<script>
export default {
  name: 'PictureCard',
  props: {
    picture_src: String,
    pic_desc: String
  }
}
</script>

Using the component:

<template>
  <div>
    <PictureCard pic_desc='some description text' picture_src='../assets/orange.png' />
  </div>
</template>

<script>
import PictureCard from './components/PictureCard.vue'
export default {
  name: 'app',
  components: {
    PictureCard
  }
}
</script>

If it is possible, I'd love to display my from a path that is passed through the component's props.

Otherwise I'd love to know some other solutions, work-arounds or knowledge on best practices in this case.

like image 421
turninglights Avatar asked Jun 17 '19 04:06

turninglights


People also ask

Can I pass function as props Vue?

You can pass strings, arrays, numbers, and objects as props. But can you pass a function as a prop? While you can pass a function as a prop, this is almost always a bad idea. Instead, there is probably a feature of Vue that is designed exactly to solve your problem.

How do I transfer data from props to Vue?

To specify the type of prop you want to use in Vue, you will use an object instead of an array. You'll use the name of the property as the key of each property, and the type as the value. If the type of the data passed does not match the prop type, Vue sends an alert (in development mode) in the console with a warning.

Are Props passed by reference Vue?

Vue does not take a copy when you pass objects via props. If you pass an object via a prop then both components will be seeing the same object. As it's the same object, any property changes made by the child will also impact the other parent.

How do I use props to pass data to child components in Vue?

The way it works is that you define your data on the parent component and give it a value, then you go to the child component that needs that data and pass the value to a prop attribute so the data becomes a property in the child component. You can use the root component (App.


2 Answers

This worked for me

<img :src="require(`@/assets/img/${filename}`)">

where filename is passed in as a String prop e.g. "myImage.png".

Make sure you use the path specific to your project.

Source: https://github.com/vuejs-templates/webpack/issues/450

Note: @ is a webpack alias for /src that is set by default in Vue projects

like image 146
M3RS Avatar answered Sep 16 '22 16:09

M3RS


After some research, I understand that my problem has to do with webpack and resolving filepaths. I used a modified version from this answer:
Vue.js dynamic images not working
and this answer:
Can't dynamically pass relative src path for imgs in Vue.js + webpack
Since the link in the second answer was dead, here's an active link to require.context documentation: https://webpack.js.org/guides/dependency-management/#requirecontext

My mistake when trying the second link's answer was that I returned only orange.png as the path, while I needed to add ./ at the beginning.

My working picture component now looks like this.

<template>
  <div>
    <img :src="resolve_img_url(picture_src)" />
    <div class="pic_sub">{{pic_desc}}</div>
  </div>
</template>
<script>
export default {
  name: 'PictureCard',
  props: {
    picture_src: String,
    pic_desc: String
  },
  methods: {
    resolve_img_url: function (path) {
      let images = require.context('../assets/', false, /\.png$|\.jpg$/)
      return images("./"+path)
    }
  }
}
</script>

I edited the regular expression to match .png and .jpg file endings. Therefore passing the prop looks like this now

<PictureCard  picture_src='orange.png' pic_desc='some picture description'/>
like image 30
turninglights Avatar answered Sep 20 '22 16:09

turninglights