简体   繁体   中英

vueJS how to import and load components dynamically as a list is rendered

I have a list being rendered.

<div v-for="msg in messages">
   <div v-if="msg.type==='component'">
      <component v-bind:is="getComponent(msg.component)" :data="msg.data" :text="msg.text"></component>
   </div>
</div>

I can get a computed property to import and load a component if I hard code the component name, but i am not able to pass a property into a computed property.

If I instead call a method, i get a never ending loop and the browser crashes.

   //This works as a computed property
   getComponent() { 
      return () => import(`@/components/data/finance/GRNISummary.vue`)
   },


   //This does not work as a computed property. Computed properties can not accept parameters
   getComponent(component) { 
      const componentsList = {
        jurisdictionEvidenceCount: '/chart/export_control/JurisdictionEvidenceCount.vue',
        grniSummary: '/data/finance/GRNISummary.vue'
      }
      return () => import(`@/components` + componentsList[component])
   },


   //This as a method crashes the browser with an infinite loop of component loads 
   getComponent(component) { 
      const componentsList = {
        jurisdictionEvidenceCount: '/chart/export_control/JurisdictionEvidenceCount.vue',
        grniSummary: '/data/finance/GRNISummary.vue'
      }
      return () => import(`@/components` + componentsList[component])
  },

Dynamic imports use Promise internally , whereas computed property takes a factory function — so, yes, as a function it does actually accept parameters. For this to work, though, you're gonna want to use require instead.

computed: {
  getComponent() {
    const componentsList = {
      jurisdictionEvidenceCount: '/chart/export_control/JurisdictionEvidenceCount.vue',
      grniSummary: '/data/finance/GRNISummary.vue'
    }

    return component => require(`@/components` + componentsList[component]);
  }
}

BTW, if you included vue in theresolve.extensions , that actually allows you to drop the extension type while importing a component. (Vue CLI should do this for you by default). Or you could confirm it by running:

vue inspect resolve.extensions

Here are my proposed changes anyway:

computed: {
  getComponent() {
    // Perhaps move this somewhere else though
    const componentsList = {
      jurisdictionEvidenceCount: 'chart/export_control/JurisdictionEvidenceCount',
      grniSummary: 'data/finance/GRNISummary'
    }

    return componentName => require(`@/components/${componentsList[componentName]}`);
  }
}

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