RIGB
RIGB

Reputation: 67

Vuetify issue - why doesn't the v-img component display anything despite the image being passed in from a valid source?

I wrote this code earlier in the summer before v-card-media was depreciated in favour of v-img. As far as I can see, I'm using v-img correctly and passing in my source through the designated src prop.

Another question mentioned a similar problem and someone suggested that v-img my not work with outdated browsers: Vuetify v-img component not loading images

I have the latest version of firefox and chrome and v-img will not display the linked image in either case. I know the information is being passed through, because all of the other data is displaying just fine. I wonder if it may be an issue with the security of the link or perhaps some configuration issue to do with links I've overlooked. Someone mentioned somewhere (I forget where now) that vue has issues loading images from relative links for custom components, but the links I'm passing in are using http. Furthermore, the images I'm passing in display fine in the avatar tile of a list component, so I believe the issue is specifically related to v-img.

All the same, I'm a clueless to what's going on. I've pasted the relative code below. If anyone has some insight into this that would be highly appreciated.

    <template>
<div id="eventCard">
      <v-container fluid grid-list-xl pb-0 grid-list-lg grid-list-md grid-list-xs>
        <v-layout row wrap>
          <v-flex
            v-for="item in shows"

            class="xs12 sm6 md4 xl4"
          >
           <v-card flat>
              <v-img
                class="secondaryFont--text"
                height="300"
                src="item.avatar"
                alt=""
              >
                <v-container fill-height fluid>
                <v-layout fill-height max no-margin>
                  <v-flex xs12 align-end flexbox max no-padding>
                        <v-container class="banner max">
                          <v-layout xs12 row>
                              <v-flex xs12 md9 v-if="item.title && item.acts" class="title">
                                  <span class="clip-text">
                                    {{item.title}}
                                    <span>(</span>
                                    <span v-if="item.acts" v-for="(act, index) in item.acts">
                                        <span>{{act.name}}</span><span v-if="index+1 < item.acts.length">, </span>
                                    </span>
                                    <span>)</span>
                                  </span>
                              </v-flex>
                              <v-flex hidden-sm-and-down xs3 text-xs-right>
                                  <span v-if="item.price" v-html="item.price" class='headline clip-text'></span>
                              </v-flex>
                          </v-layout>
                      </v-container>
                  </v-flex>
                </v-layout>
                </v-container>
              </v-img>
              <v-card-text class='primaryFont--text'>
                <div>
                  <span v-if="item.genre" v-html="item.genre"></span>
                      <span v-if="item.doors"> — Doors @ {{item.doors}}</span>
                      <span v-if="item.age"> ({{item.age}}+)</span>
                      <span v-if="item.location"> — {{item.location}}</span>
                  <br>
                  <span v-if="item.date" v-html="item.date"></span>
                </div>
              </v-card-text>
            </v-card>
        </v-flex>
      </v-layout>
    </v-container>

This is the css code for the above component:

.md-active {
    background-color: red;
}

.center {
    display: flex;
    justify-content: center;
    text-transform: capitalize;
}

.banner {
    margin-top: 0px;
    background-color: rgba(0, 0, 0, .6);
}

.clip-text {
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    display: flow-root;
}

.max {
    max-width: 100%;
}
.card__media__content {
    max-width: 100%;
}

.card {
    cursor: pointer;
}

.no-padding {
    padding: 0px !important;
}

.no-margin {
    margin: 0px !important;
}

Upvotes: 5

Views: 57231

Answers (10)

Eric Milliot-Martinez
Eric Milliot-Martinez

Reputation: 4586

Slightly different scenario, but Googling brought me here so I figure I'd share it.

<template>
    <v-img height="450" :src='gif' />
</template>

<script setup lang="ts">
import gif from '@/assets/gifs/success_gif_1.gif'
</script>

Upvotes: 0

The code does not work and the first one encounters an error. It is better to try the code of the second sample. I did it and it was right:

this does not work ===>

<v-img :src="require(item.path)" />

this is correct ===>

:src="require(`../../assets/image/best-project/${card.img}`)"

Upvotes: 3

Irving Caamal
Irving Caamal

Reputation: 51

Nuxt.js integrate a better approach to do/fix this check the docs for more info about this.

but now the configuration is easier and less confusing ('cause you don't need to really understand webpack)

export default {
  build: {
    extend(config, { isClient, loaders: { vue } }) {
      // Extienda solo la configuración de Webpack para el paquete de cliente
      if (isClient) {
        vue.transformAssetUrls.video = ['src', 'poster'],
        vue.transformAssetUrls['v-img']= ['src', 'blank-src']
      }
    }
  }
}

This is the solution in the Vuetify case, hope it helps.

Upvotes: 2

ncutixavier
ncutixavier

Reputation: 651

I just had the same issue, but I resolved with using v-bind. For more about vuejs and v-bind, use this video

<v-img height="200px" v-bind:src="item.image" />

Upvotes: 2

Singingsongs
Singingsongs

Reputation: 11

i think vue has an absolute path to all image files in the img folder. this worked for me <v-img src="img/avater.jpg" /> which relatively suppose to be <v-img src="../../../public/img/avater.jpg" />

Upvotes: 0

Calil
Calil

Reputation: 67

just for the record if anyone have the same problem as me in the future:

if you are trying to use the v-image in a v-for loop the code should look like this:

    <v-col
      v-for="(testimonial, i) in testimonials"
      :key="i"
      cols="12" md="4"
    >
      <v-card :id="testimonial.title">

        <v-img :src="require(`../assets/img/${testimonial.src}`)"></v-img>

        <v-col v-text="testimonial.title"></v-col>
        <v-card-subtitle v-text="testimonial.description"></v-card-subtitle>
      </v-card>
    </v-col>

use the fixed part of the path as a string in the require() and just the image as a variable. data properties should look like:

testimonials: [
        {
          src: 'testimonials-1.jpg',
          title: 'Some name',
          description: 'Lorem ipsum'
        },
        {
          src: 'testimonials-2.jpg',
          title: 'Some name',
          description: 'Lorem ipsum'
        },

Upvotes: 5

Debu Shinobi
Debu Shinobi

Reputation: 2562

<v-img
      class="secondaryFont--text"
      height="300"
      src="item.avatar"
      alt=""
      >

Here, instead of just src, you should be using :src. Note: :src is know as bounded attribute.

P.S.: If you paste the code of script tag it would be more convenient to help you.

Upvotes: 0

JTInfinite
JTInfinite

Reputation: 380

I have also used require in my components data property, which works:

<template>
    <v-img :src="myImage"></v-img>
</template> 

export default {
    data () {
        return {
            myImage: require('@/path/to/image')
        }
    }
}

Upvotes: 10

Mirza Andriamanamisoa
Mirza Andriamanamisoa

Reputation: 421

You have to use require for relative image paths, because Vue loader doesn't do that automatically for custom components.

<v-img :src="require(item.path)" />

Explanation in Vuetify FAQ

Upvotes: 5

Anson Low.Z.F
Anson Low.Z.F

Reputation: 236

This is how I solve the problem,

<v-img :src="require('item.avatar')" aspect-ratio="1"></v-img>

It's should display the image correctly

Hope it help you

Upvotes: 21

Related Questions