Reputation: 33
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.
Upvotes: 2
Views: 1650
Reputation: 7187
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.
Upvotes: 1