Robert C. Holland
Robert C. Holland

Reputation: 1813

Vue.js equivalent of appendChild to dynamically add new element/component?

In Vue.js, I have a var app = new Vue({...}); and I have a component Vue.component('mycomponent', ... where I can use such component without any issue by directly adding <mycomponent></mycomponent> in html. What I wish to do is to dynamically add those component on demand maybe after a button click or when some other such event takes place. In raw JS, I'd use document.createElement... when event fires and then do el.appendChild.. to add it into html. How would I do the same with Vue.js ?

I'm not doing anything fancy with node js. This is on a single html page with <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> in the <head>.

Upvotes: 5

Views: 10805

Answers (1)

Decade Moon
Decade Moon

Reputation: 34306

To do this the "Vue way" usually involves the use of v-if, v-for or <component>, depending on what you want to do:

  • Use v-if to conditionally show a component/element based on a condition.
  • Use v-for to render a list of components/elements.
  • Use <component> to render a dynamic component/element.

So to achieve what you described in your question, you can declare a boolean data property visible like this:

data() {
  return {
    visible: false
  }
}

and use it with v-if to control the visibility of a component in the template:

<mycomponent v-if="visible"></mycomponent>

This requires that <mycomponent> exist in the template upfront. If you don't know what kind of component you want to show, then you can either include each possibility in the template and display the one you want based on some condition:

<comp1 v-if="comp1Visible"></comp1>
<comp2 v-if="comp2Visible"></comp2>
<comp3 v-if="comp3Visible"></comp3>

or you can use <component> together with another data property (comp) which you can set to the name of the component you want to display:

<component v-if="visible" :is="comp"></component>

What you described (document.createElement followed by el.appendChild) does not exist in Vue. Vue has a strict rendering mechanism which you need to work with; it isn't possible to dynamically instantiate components and stick them into the DOM randomly. Technically you can do comp = new Vue() as an equivalent to document.createElement and then el.appendChild(comp.$el), but that probably isn't what you want to do because you would be creating an independent Vue instance that you would have to manage manually with no easy way of passing data around.

Upvotes: 5

Related Questions