How to make your components dynamic in Vue.js
Tags: vue, javascript, tutorial
Published: 2019-09-17 16:33:14

---
title: How to make your components dynamic in Vue.js
published: true
tags: vue, javascript, tutorial
canonical_url: https://blog.logrocket.com/how-to-make-your-components-dynamic-in-vue-js/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/gxcwyg3u6vpoyc11n1sc.png
---
**Written by [Nwose Lotanna](https://blog.logrocket.com/author/nwoselotanna/)**✏️

This post serves as an introduction to the ways you can reference HTML elements in your components in Vue.js. You can toggle between views or component templates by using the Vue router or by creating dynamic components.

The Vue router is used to navigate between views or component templates in the DOM. To use the Vue router, define routes in a routes component and indicate to Vue that the new component should be mounted on an event, such as click.

This is the proper way to handle navigations in sidebar and menu components within the user interface.

If you’ve ever wanted the option to switch between two arbitrary components mounted in the DOM without creating routes, you may want to employ dynamic components.

### Dynamic components

Vue dynamic components enable users to switch between two or more components without routing, and even retain the state of data when switching back to the initial component.

The central idea is to let users dynamically mount and unmount components in the user interface without using routers.

### Why are dynamic components important?

When designing your user interface, you’ll want some form of flexibility to show or hide nested components based on the application state. Dynamic components provide that platform in an efficient and simple way.

The feature saves you from a lot of code since you can easily achieve dynamic components with Vue conditional structures such as v-if and v-else. You can use conditional structures to achieve dynamic components by using a placeholder approach to easily bind logic to the component.

This approach ensures that your presentation is always clean and unambiguous.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

### Before you can create dynamic components in Vue.js, you will need the following in your PC:

- Node.js version 10.x and above installed. You can verify that you have Node.js version 10.x by running the command below in your terminal/command prompt:  
`node -v`
- A code editor (I highly recommend using Visual Studio Code).
- Vue’s latest version, installed globally on your machine.
- Vue CLI 3.0 installed on your machine. To do this, uninstall the old CLI version first:

`npm uninstall -g vue-cli`  
Then, install the new one:

`npm install -g @vue/cli`  
– Download a Vue starter project [here](https://github.com/viclotana/vue-canvas).  
– Unzip the downloaded project.  
– Navigate into the unzipped file and run the command to keep all the dependencies up-to-date:

`npm install`

### Dynamic components syntax

Vue offers a special template element for dynamic components simply called **component**. The syntax looks like this:

```jsx
<component v-bind:is=”currentComponent”></component>
```

The **component element** can also be a self-closing tag:

```jsx
<component v-bind:is=”currentComponent”/>
```

The first option works best for browsing compatibility purposes.

### Demo

Download [the starter project](https://github.com/viclotana/vue-canvas)and open it in VS Code for some examples of dynamic components. The starter project allows you to access an existing test component, create a second test component, and switch between the two.

Navigate to the components folder and create a new file. Name the file `Test2.vue` and copy the following code block into the file:

```jsx
<template>
  <div><h1>I am Test 2</h1>
  </div>
</template>
<script>
export default {
  name: 'Test2',
  props: {
    msg: String
  }
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>
```

Now that you have a second component, go to the `App.vue` file and register the component:

```jsx
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <Test />
    <Test2 />
  </div>
</template>
<script>
import Test from './components/Test.vue'
import Test2 from './components/Test2.vue'
export default {
  name: 'app',
  components: {
    Test, Test2
  }
}
</script>
```

The two test components are now nested in the root app component. If you want to mount only one component and then dynamically switch to the other, you have to create a dynamic component.

Copy the code block below into the template section of your `app.vue` file:

```jsx
<template>
   <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <component is="Test" />
   </div>
</template>
```

Next, run the application with the following serve command:

`npm run serve`

You’ll see that only the Test 1 component shows up.

![Test 1 component Vue](https://blog.logrocket.com/wp-content/uploads/2019/09/test-1-nocdn.png)

This is exactly the response you’d get if the Test 1 element was only specified in the template. To make the component dynamic, we can bind it to a set property with the v-bind directive.

```jsx
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <component v-bind:is="component" />
  </div>
</template>
<script>
import Test from './components/Test.vue'
import Test2 from './components/Test2.vue'
export default {
  name: 'app',
  components: {
    Test, Test2
  },
  data (){
    return {
      component:"Test"
    }
  }
}
</script>
```

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.

### Adding method calls

You can add method calls to control the logic for dynamic display of the component. Component elements give you access to every construct in the Vue instance.

The following is an example of a small method for toggling these two components:

```jsx
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <component v-bind:is="component" />
    <button v-on:click="toggle">Toggle</button>
  </div>
</template>
<script>
import Test from './components/Test.vue'
import Test2 from './components/Test2.vue'
export default {
  name: 'app',
  components: {
    Test,
     Test2
  },
  data (){
    return {
      component:"Test2"
    }
  },
  methods: {
    toggle(){
      if (this.component === Test) {
        this.component = Test2;
      } else {
        this.component = Test;
      }
    }
  }
}
</script>
```

### Keeping data values alive as you switch

As the Vue team built this feature, they opted to extend its capabilities to include storing data values per state.

To store this data, Vue provides a template element called **keep-alive**. Using keep-alive, you can ensure your component state stays exactly as you left it after you switch back from one component to the other.

For example, if you click on a link or enter a value in a text box and then switch components, keep-alive brings you back to the same link or text box you were using when you switch back.

To enable keep-alive, go to the template section of your `app.vue` file and wrap the component element with the keep-alive element:

```jsx
<keep-alive>
  <component v-bind:is="component" />
</keep-alive>
```

To see if it works, add a form element to your `Test.vue` file by adding the following code block to the template section:

```jsx
<template>
  <div><h1>I am Test 1</h1>
       <form>
         First name:<br>
         <input type="text" name="firstname"><br>
         Last name:<br>
         <input type="text" name="lastname">
       </form>
  </div>
</template>
```

When you save all project files, run the application again. Type into the input boxes, switch components, and toggle back to the original component. You’ll notice the values you typed prior to switching components are exactly as you left them.

![A gif demonstrating how to toggle between two components](https://blog.logrocket.com/wp-content/uploads/2019/09/Test-1-Test-2-gif-nocdn.gif)

### Conclusion

This has been an introduction to using dynamic components in your Vue.js workflow. You also now have the ability to extend the powers of the component element through keep-alive.

This is a great tool for building user interfaces and can be applied to a variety of different use cases. Happy hacking!
* * * 
**Editor's note:** Seeing something wrong with this post? You can find the correct version [here](https://blog.logrocket.com/how-to-make-your-components-dynamic-in-vue-js/).

## Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps
 
![LogRocket Dashboard Free Trial Banner](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png?resize=1200%2C677&ssl=1)
 
[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
 
[Try it for free](https://logrocket.com/signup/).
* * *
The post [How to make your components dynamic in Vue.js](https://blog.logrocket.com/how-to-make-your-components-dynamic-in-vue-js/) appeared first on [LogRocket Blog](https://blog.logrocket.com).