Dynamic Component Rendering in Vue.js: A Practical Guide

By Maulik Paghdal

21 Dec, 2024

•   4 minutes to Read

Dynamic Component Rendering in Vue.js: A Practical Guide

Vue.js is celebrated for its flexibility, especially when it comes to rendering components dynamically. Dynamic component rendering allows you to switch components on the fly, enabling the creation of flexible and reusable user interfaces. This feature is especially useful for building tabs, modals, dashboards, and other UI components where the displayed content changes based on user interaction or data.

In this guide, we’ll explore dynamic component rendering in Vue.js, including practical examples and tips for efficient implementation.

What Is Dynamic Component Rendering?

Dynamic component rendering allows you to load and display Vue components at runtime. Instead of hardcoding components in your template, you can use Vue's component element or dynamic imports to render them based on a condition, user input, or data-driven logic.

Why Use Dynamic Components?

Dynamic components come with several benefits:

  • Flexibility: Render components based on user actions or application state.
  • Reusability: Avoid duplicating code by reusing components dynamically.
  • Performance: Load only the required components at runtime, reducing the initial load time.

Dynamic Component Basics

Vue provides the <component> element for dynamic rendering. You can bind a component name or reference to the :is attribute.

Example 1: Basic Dynamic Component Rendering

Here’s a simple example with three components: Home, About, and Contact.

Home.vue:

<template>
  <div>Welcome to the Home page!</div>
</template>

About.vue:

<template>
  <div>About us page content goes here.</div>
</template>

Contact.vue:

<template>
  <div>Get in touch with us!</div>
</template>

App.vue:

<template>
  <div>
    <button @click="currentComponent = 'Home'">Home</button>
    <button @click="currentComponent = 'About'">About</button>
    <button @click="currentComponent = 'Contact'">Contact</button>
    
    <component :is="currentComponent"></component>
  </div>
</template>

<script>
import Home from './components/Home.vue';
import About from './components/About.vue';
import Contact from './components/Contact.vue';

export default {
  data() {
    return {
      currentComponent: 'Home', // Default component
    };
  },
  components: {
    Home,
    About,
    Contact,
  },
};
</script>

Dynamic Component with Props

You can pass props to dynamically rendered components just like static ones.

Example:

<template>
  <div>
    <component :is="currentComponent" :message="message"></component>
  </div>
</template>

<script>
import Home from './components/Home.vue';
import About from './components/About.vue';

export default {
  data() {
    return {
      currentComponent: 'Home',
      message: 'Hello from parent!',
    };
  },
  components: {
    Home,
    About,
  },
};
</script>

Home.vue:

<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  props: ['message'],
};
</script>

Using Dynamic Imports for Lazy Loading

Dynamic imports are a powerful feature that allows you to load components only when needed, improving application performance.

Example:

<template>
  <div>
    <button @click="loadComponent('Home')">Home</button>
    <button @click="loadComponent('About')">About</button>
    <component :is="asyncComponent"></component>
  </div>
</template>

<script>
export default {
  data() {
    return {
      asyncComponent: null, // Placeholder for dynamically imported component
    };
  },
  methods: {
    loadComponent(componentName) {
      import(`./components/${componentName}.vue`).then((module) => {
        this.asyncComponent = module.default;
      });
    },
  },
};
</script>

Real-World Use Cases

1. Tabs

Dynamic components are perfect for building tabbed interfaces.

Example:

<template>
  <div>
    <ul>
      <li v-for="tab in tabs" :key="tab.name" @click="currentTab = tab.component">
        {{ tab.name }}
      </li>
    </ul>
    <component :is="currentTab"></component>
  </div>
</template>

<script>
import Tab1 from './components/Tab1.vue';
import Tab2 from './components/Tab2.vue';

export default {
  data() {
    return {
      tabs: [
        { name: 'Tab 1', component: 'Tab1' },
        { name: 'Tab 2', component: 'Tab2' },
      ],
      currentTab: 'Tab1',
    };
  },
  components: {
    Tab1,
    Tab2,
  },
};
</script>

2. Dynamic Forms

Render different form components based on the type of data being collected.

Best Practices for Dynamic Components

  1. Lazy Load Components: Use dynamic imports to load components only when required, reducing the initial bundle size.
  2. Handle State Carefully: Ensure components maintain their internal state if reused dynamically.
  3. Use Key Attribute: When switching components dynamically, use the key attribute to reset the state and lifecycle hooks.

Example:

<component :is="currentComponent" :key="currentComponent"></component>
  1. Optimize Directory Structure: Store dynamic components in a dedicated folder to keep your project organized.

Conclusion

Dynamic component rendering in Vue.js empowers developers to build flexible, efficient, and user-friendly applications. Whether you're building tabs, dashboards, or dynamic forms, leveraging Vue's dynamic component features can significantly streamline your development process.

By combining features like dynamic imports and the component element, you can optimize performance and create highly maintainable codebases. Start experimenting with dynamic components in your next Vue.js project!

Topics Covered