简体   繁体   中英

Dynamic Vue component import path using template literals

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM