VueJS Dynamic Component and Why it is Useful
/ Let us look at how we can dynamically use components using the VueJS "<component />" tag. Let us improve our code and optimize it by simplifying our code.
Sometimes, it's useful to dynamically switch between components, like in a tabbed interface. The above is made possible by Vue's <component>
element with the special is
attribute. In this article I will show a sample why dynamic form is very useful.
You can the source code HERE. Assuming we want to render the component based on a key, As you can see in the code below we created a page that displays the component based on the selected page.
<script lang="ts" setup>
import { ref } from "vue";
import PageOne from "./components/PageOne.vue";
import PageTwo from "./components/PageTwo.vue";
import PageThree from "./components/PageThree.vue";
const selectedPage = ref("one");
</script>
<template>
<h1>This Are Pages</h1>
<button @click="selectedPage = 'one'">Select Page One</button>
<button @click="selectedPage = 'two'">Select Page Two</button>
<button @click="selectedPage = 'three'">Select Page Three</button>
<PageOne v-if="selectedPage == 'one'" />
<PageTwo v-if="selectedPage == 'two'" />
<PageThree v-if="selectedPage == 'three'" />
</template>
In the code above, we added the 3 components and based on the condition, it only shows the component based on the selected value from "one", "two", and "three". This is good but can become a problem if we have too many components to render, and it would be a hassle if we will add more components later on, right? It would be awesome if can create a way to automate this when ever we add a new component, right?
So the first thing to do is to put them in a variable or you can put it in:
import PageOne from "./components/PageOne.vue";
import PageTwo from "./components/PageTwo.vue";
import PageThree from "./components/PageThree.vue";
const pagesToRender = [
{
title: "Page One",
key: "one",
component: PageOne,
},
{
title: "Page Two",
key: "two",
component: PageTwo,
},
{
title: "Page Three",
key: "three",
component: PageThree,
},
];
And Then we can turn our template to look something like this:
<template>
<h1>This Are Pages</h1>
<button v-for="page in pagesToRender" :key="'btn-' + page.key" @click="selectedPage = page.key">{{ page.title }}</button>
<component :is="pagesToRender.find((item) => item.key == selectedPage)?.component as any" />
</template>
Now, our buttons are dynamic and automatically renders button with a label of title, and if we click the button it will set the selectedPage
value based on the object key which is "one", "two", and "three".
We then used the `component` tag, and we used the `is` property for us to render the component dynamically based on the selected key, and then returns the component property which includes the component we imported.
So with that said our code should look like this:
<script lang="ts" setup>
import { ref } from "vue";
import PageOne from "./components/PageOne.vue";
import PageTwo from "./components/PageTwo.vue";
import PageThree from "./components/PageThree.vue";
const selectedPage = ref("one");
const pagesToRender = [
{
title: "Page One",
key: "one",
component: PageOne,
},
{
title: "Page Two",
key: "two",
component: PageTwo,
},
{
title: "Page Three",
key: "three",
component: PageThree,
},
];
</script>
<template>
<h1>This Are Pages</h1>
<button v-for="page in pagesToRender" :key="'btn-' + page.key" @click="selectedPage = page.key">{{ page.title }}</button>
<component :is="pagesToRender.find((item) => item.key == selectedPage)?.component as any" />
</template>
We can also create an external TypeScript/JavaScript, a place for us to dynamically edit the menu menu. So in this example I created a file in `src/utility/PagesToRender.ts` that contain this code:
import PageOneVue from "@/components/PageOne.vue";
import PageThreeVue from "@/components/PageThree.vue";
import PageTwoVue from "@/components/PageTwo.vue";
const pagesToRender = [
{
title: "Page One",
key: "one",
component: PageOneVue,
},
{
title: "Page Two",
key: "two",
component: PageTwoVue,
},
{
title: "Page Three",
key: "three",
component: PageThreeVue,
},
];
export default pagesToRender;
Then we can just import it to our main template like this:
<script lang="ts" setup>
import { ref } from "vue";
import pagesToRender from "./utility/PagesToRender";
const selectedPage = ref("one");
</script>
<template>
<h1>This Are Pages</h1>
<button v-for="page in pagesToRender" :key="'btn-' + page.key" @click="selectedPage = page.key">{{ page.title }}</button>
<component :is="pagesToRender.find((item) => item.key == selectedPage)?.component as any" />
</template>
Imported the pagesToRender
from our utility. Now whenever we add a page we can just go to our pageToRender
utility and add more pages.
Conclusion
We use component
tags to dynamically render our component, this is useful because we don't have to write every component we created, instead using the component
tag we can render our component using a single tag. I hope you learn something from this short article! aloha! mabuhay!