Skip to content

Instantly share code, notes, and snippets.

@james2doyle
Created December 15, 2020 17:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save james2doyle/ef998ad04d173759bcec40009f2ca8b4 to your computer and use it in GitHub Desktop.
Save james2doyle/ef998ad04d173759bcec40009f2ca8b4 to your computer and use it in GitHub Desktop.
Usage of a dynamically imported component that comes from a prop in Vue 3
<template>
<button type="button">
<div v-if="!button">&nbsp;</div>
<!-- the `is` prop can take a full on component! -->
<component :is="button" v-else />
</button>
</template>
<script>
import { defineComponent, ref } from '@vue/composition-api';
export default {
name: 'IconButton',
props: {
icon: {
type: String,
required: true,
},
},
setup({ icon }) {
const button = ref(null);
// loads the icon dynamically
import(`Assets/icons/${icon}.svg`)
.then(module => {
button.value = module.default;
});
return { button };
},
};
</script>
@risha700
Copy link

the import statement is greedy enough to load all the files in the path provided! any ideas to load only specific file!

@ngekoding
Copy link

I try to import heroicons, but I got an error.

Uncaught (in promise) TypeError: Failed to resolve module specifier '@heroicons/vue/outline/LightningBoltIcon'

And here is my code:

const iconComponent = ref(null)
const iconName = props.icon; // e.g. HomeIcon
import(`@heroicons/vue/outline/${iconName}`)
  .then(module => {
    iconComponent.value = module.default
  })

Any idea?

@jlubojacka
Copy link

Maybe someone finds this helpful. You can use defineAsyncComponent .
(Vue 3 Composition API)

<template>
  <button type="button">
    <component :is="AsyncComp" />
  </button>
</template>

<script setup>
import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() =>
  import('@/assets/icon.svg')
)
</script>

It's possible to pass component's name as prop and create more complex logic too.

<script setup>
import { defineAsyncComponent } from 'vue'

const props = defineProps({
  componentName: {type: String, required: true},
})

const AsyncComp = defineAsyncComponent(() =>
  if (props.componentName){
    import(`@/components/{props.componentName}.vue`)
  } else {
    import('@/components/DefaultComponent.vue')
  }
)
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment