2

EDIT

So, the following technically answers the question, and is based on Husam's answer.

beforeCreate: function () {
  this.$options.components.Background = () =>
    import(`~/assets/img/marketing/user-group-backgrounds/user-group-bg-${this.bg}.svg`)
}

Will work as requested, fetching the background based on the bg prop. Only problem is, it is an SVG, not a .vue file, and not being passed through vue-svg-loader, so I get the error Invalid Component definition.


ORIGINAL QUESTION

I have a vue/Nuxt.js app in which we are using vue-svg-loader (documentation).

The component in question (child) retrieves several bits of data as props from an object defined in its parent (parent) component.

parent loops over the top entries in the object using v-for, generating a child for each.

Each child needs a different background image, whose path can be determined using:

`~/path/to/image/background-number-${prop-from-parent}`

Since vue-svg-loader treats SVG images as components, and it provides several benefits I would like to leverage, I am trying to devise a solution that will allow me to do something along these lines:

<template>
  <div class="child">
    <Background class="background-image" />
    <p>
      ...
    </p>
  </div>
</template>

<script>
const Background = import(`~/path/to/image/background-number-${prop-from-parent}`)

export default {
  components: {
    Background
  },
  props: {
    prop-from-parent: { type: String, required: true }
    }
  }
</script>

Doing so returns:

NuxtServerError
render function or template not defined in component: Background

I have done research and seen that the only solution seems to be of this sort:

import BackgroundOne from 'path/to/background-one.svg'
import BackgroundTwo from 'path/to/background-two.svg'
import BackgroundThree from 'path/to/background-three.svg'

export default{
  components: {
    BackgroundOne,
    BackgroundTwo,
    BackgroundThree,
  }
}

(source)

Which is just silly. I could move the background insertion logic the parent component and insert it into each child using <slot />, and it would serve my purpose, but that seems much too declarative. My list is currently 10 items long and may grow, and almost certainly will change in the future.

1
  • Try const Background = require(~/path/to/image/background-number-${prop-from-parent}.svg) Commented Oct 1, 2018 at 19:27

1 Answer 1

1

You can try this technique ..

<script>
export default {
  props: {
    prop-from-parent: { type: String, required: true }
  },
  beforeCreate: function () {
    const filePath = `~/path/to/image/background-number-${this.prop-from-parent}`
    this.$options.components.Background = require(filePath).default
  }
}
</script>

As seen here. It might work in your case.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, that's definitely super helpful and pointed me in the right direction.
You're most welcome. Please make sure to post here the final solution to your problem so that other people can benefit from it :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.