In order to use a dynamically-defined single page component, we use the component
tag, thusly:
<component v-bind:is="componentName" :prop="someProperty"/>
...
import DynamicComponent from '@/components/DynamicComponent.vue';
...
components: {
DynamicComponent
},
props: {
componentName: String,
someProperty: null,
}
The problem is, this isn't really very dynamic at all, since every component we could ever possibly want to use here needs to be not only imported statically, but also registered in components
.
We tried doing this, in order at least to avoid the need to import everything:
created() {
import(`@/components/${this.componentName}.vue`);
},
but of course this fails, as it seems that DynamicComponent
must be defined before reaching created()
.
How can we use a component that is truly dynamic, i.e. imported and registered at runtime, given only its name?
To make the component dynamic, we can bind it to a set property with the v-bind directive. Your component is now bound with the component property in the data. If you switch the component to Test2 , it will automatically mount the Test 2 component. Test it out on your browser.
To create a dynamic page you need to add an underscore before the . vue file name or before the the name of the directory, if you want the directory to be dynamic. You can name the file or directory anything you want but you must prefix it with an underscore.
Nuxt offers better SEO improvement with its server-side rendering feature, faster development with an auto-generic router, public share features, and management with great configuration options and meta tags methods, automatic code splitting with pre-rendered pages — all of this is impossible or extremely complex to ...
We can pass props to dynamic components using the v-bind directive. To display dynamic components, we add the component component with the is prop. currentComponent is a string with the component name. v-bind has an object with the props that we want to pass to whatever component is being rendered now.
From the documentation: Emphasis mine
<!-- Component changes when currentTabComponent changes --> <component v-bind:is="currentTabComponent"></component>
In the example above,
currentTabComponent
can contain either:
- the name of a registered component,
- or a component’s options object
If currentTabComponent
is a data property of your component you can simply import the component definition and directly pass it to the component tag without having to define it on the current template.
Here is an example where the component content will change if you click on the Vue logo.
Like this:
<component :is="dynamic" />
...
setComponentName() {
this.dynamic = () => import(`@/components/${this.componentName}.vue`);
},
Solution for Nuxt only
As of now its possible to auto-import components in Nuxt (nuxt/components
). If you do so, you have a bunch of components ready to be registered whenever you use them in your vue template e.g.:
<MyComponent some-property="some-value" />
If you want to have truly dynamic components combined with nuxt/components
you can make use of the way Nuxt prepares the components automagically. I created a package which enables dynamic components for auto-imported components (you can check it out here: @blokwise/dynamic
).
Long story short: with the package you are able to dynamically import your components like this:
<NuxtDynamic :name="componentName" some-property="some-value" />
Where componentName
might be 'MyComponent'
. The name can either be statically stored in a variable or even be dynamically created through some API call to your backend / CMS.
If you are interested in how the underlying magic works you can checkout this article: Crank up auto import for dynamic Nuxt.js components
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With