6

I'm building a banner with Vue that needs to have a dynamic background, however, it doesn't seem to be working. Not sure what I'm doing wrong. I've tried a few other ways and it works if I do an image tag something like

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

But obviously this needs to be an inline background image.

Code:

component

<template>
  <div
    class="w-full h-64 bg-auto bg-no-repeat bg-center lg:bg-cover relative"
    :style="{ backgroundImage: url(require('@/assets/images/' + backgroundImage))}"
  >
    <div class="w-full h-full flex flex-col justify-center items-center text-white px-6">
      <div class="hero-text rounded text-center py-8 px-12">
        <p class="text-base lg:text-md uppercase font-medium">{{ smallLeadingText }}</p>
        <h1 class="text-xl md:text-3xl lg:text-5xl uppercase font-bold">{{ mainText }}</h1>
        <p class="text-base lg:text-md">{{ subText }}</p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "PageHero",
  props: {
    backgroundImage: String,
    smallLeadingText: {
      type: String,
      required: false
    },
    mainText: {
      type: String,
      required: true
    },
    subText: {
      type: String,
      required: false
    }
  }
};
</script>

View

<PageHero
  backgroundImage="mc-background.png "
  smallLeadingText="Powerful, secure &amp; affordable"
  mainText="Minecraft hosting"
  subText="Plans suitable for all budgets"
/>
Ben Bagley
  • 733
  • 1
  • 9
  • 22
  • Would you be able to give an example @Phil? If you don't mind – Ben Bagley Mar 26 '20 at 01:16
  • So I tried your code @Phil but it removes the code https://gyazo.com/09f006c0bdef02156051924a9f30037b if I remove the `:style` the code shows without the background – Ben Bagley Mar 26 '20 at 01:18
  • I may have messed something up in the comment so I've moved it to an answer below. I'd definitely preference using computed properties instead of doing everything inline – Phil Mar 26 '20 at 01:22
  • FYI, I've always found it works best to use kebab-cased attribute names when passing props, ie `background-image="mc-background.png"`. See https://vuejs.org/v2/guide/components-props.html#Prop-Casing-camelCase-vs-kebab-case and https://vuejs.org/v2/style-guide/#Prop-name-casing-strongly-recommended – Phil Mar 26 '20 at 01:56

2 Answers2

9

Looks like you've just got some syntax errors in your style attribute around string quoting. Try

<div :style="{ backgroundImage: `url(${require('@/assets/images/' + backgroundImage)})` }">

Might be easier to create some computed properties to resolve everything though

computed: {
  bgImage () {
    return require('@/assets/images/' + this.backgroundImage)
  },
  inlineStyle () {
    return {
      backgroundImage: `url(${this.bgImage})` 
    }
  }
}

and

<div :style="inlineStyle">

Demo ~ https://codesandbox.io/s/crimson-sky-ehn9r

Phil
  • 157,677
  • 23
  • 242
  • 245
  • So I tried your code but it removes the code gyazo.com/09f006c0bdef02156051924a9f30037b if I remove the :style the code shows without the background even with the computed route. – Ben Bagley Mar 26 '20 at 01:23
  • Same issue for both examples just shows the component as commented `<--->` and doesn't actually show with the `style` bind. – Ben Bagley Mar 26 '20 at 01:32
  • @debugabug works fine for me. I've added a demo link – Phil Mar 26 '20 at 01:38
  • Hey, here is a small video of what is happening, not sure why as everything is correct given the example link. https://i.gyazo.com/91d584adb32ef0f148e1a13397b3c1d6.mp4 – Ben Bagley Mar 26 '20 at 02:27
  • @debugabug There's three errors in your browser console. What are they? – Phil Mar 26 '20 at 02:55
  • Here you go @phil https://gyazo.com/3b275ca7bb2ea9f3e0bf24364fef4c5a – Ben Bagley Mar 26 '20 at 15:49
0

Point 1: Syntax

While the other solution does not work for me, this does:

<div :style="{ backgroundImage: `url(${'src/assets/images/' + backgroundImage})`}"></div>

Of course, you need the height property to display the image.

This solution does not include "require", which will save you the error of "require" not defined.

Point 2: Path

You can go to the browser's console, Network tab, and check if the image actually gets loaded. The path may be incorrect, for example:

'../assets/images/'

and

'@/assets/images/' 

did not work for me, but this:

'src/assets/images' 

and this:

src/images

did, depending on the project. I have not looked into why 'assets' was skipped for some projects and not others, but for now you can try these options.