3

I'm trying to dynamically append vue components to my app using jquery. But nothing happens and appended element not rendering.

<div id="app">


</div>

<script>
  Vue.component('my-component', {
     template: '<p>This is component</p>'
  });

  var Vue = new Vue({
    el: '#app'
  });

 $(document).ready(function(){
   $('#app').append('<my-component></my-component>');
 })
</script>

My desired result is that when appending <my-component></my-component> to #app, That become to specified template.

8
  • Why you want to do that ? That is not the recommended way in vue js. Commented Apr 21, 2017 at 10:30
  • because some items on the page, loading by ajax and i want load template only when needed Commented Apr 21, 2017 at 10:32
  • I'm new in Vue. What is proper way ? Commented Apr 21, 2017 at 10:34
  • Proper way is handle that ajax logic into the vue instance, and then you can manipulate with VueJS displaying components, when you got response without dom conflicts. Commented Apr 21, 2017 at 10:36
  • @BelminBedak: Thanks for replying. any example or tutorial ? Commented Apr 21, 2017 at 10:37

4 Answers 4

2

this worked for me

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
    <div id="app">
        <div id="agregame">

        </div>


        <button type="button" id="agregame_click">Add click</button>
  <button type="button" v-on:click="addForm()">Add Form</button>
</div>

<script>


var vm =new Vue({
    el: '#app',
  data: {
    range:0,
    questions:[]
  },

  methods: {
    addForm: function() {
        vm.questions.push({
      firstName: 'Walter',
      lastName: 'White',
      alias: 'Heisenberg'
    })

        var Profile = Vue.extend({
  template:`
  <div id="mount-point">
<h3>Guest Content</h3>
  <ul>
    <li v-for="question in questions">
  {{question.firstName}}
    </li>
  </ul>
  </div>
`,
  data: function () {
    return {
         questions: vm.questions

            }
        }
})
// create an instance of Profile and mount it on an element
new Profile().$mount('#mount-point')
    }
  }
})

jQuery(document).ready(function($) {
    $("#agregame_click").on("click", function(){

        $("#agregame").html('<div id="mount-point"></div>');
        vm.$forceUpdate()
         vm.$emit('my-form');
        alert()
    })
});


</script>
</body>
</html>
Sign up to request clarification or add additional context in comments.

Comments

2

You can try this:

var component = {
    template: '<p>This is component</p>'
};

Vue.component('my-component', component);
var myComponent = Vue.extend(component);
var component = new myComponent().$mount();

$('#app').append(component.$el);

If you need to pass to your component some props

var component = new myComponent({
    propsData: {
        values: 'my-value'
    }
}).$mount();

Credits: https://medium.com/@ezkeromar/append-some-vue-js-component-dynamically-to-the-dom-using-jquery-abb92f0425ce

Comments

2

The proper way to handle this is through conditional rendering:

<my-component v-if="value == value_after_ajax"></my-componment>

You can put the right condition inside v-if to show the template only when it is required after the ajax call.

Read more about this here https://v2.vuejs.org/v2/guide/conditional.html#v-if

5 Comments

Thanks but this is not my answer. How this component can append dynamically ?
When we use frameworks like vue.js/angular, we have to do the stuffs in their respective way. Using jQuery append you are going to insert the HTML dynamically. Similarly using v-if the DOM will not be there until the condition is true. The HTML will be inserted into DOM by vue.js only when the condition is true. The append part is automatically done by vue framework.
In addition to previous comment, what you are trying to achieve with jQuery is not possible.
Ok i will try this
Please accept the answer if that helps you to achieve the desired result.
0

You can use dynamic components for that https://v2.vuejs.org/v2/guide/components.html#Dynamic-Components

per documentation:

var vm = new Vue({
  el: '#example',
  data: {
    currentView: 'home'
  },
  components: {
    home: { /* ... */ },
    posts: { /* ... */ },
    archive: { /* ... */ }
  }
})

But for change currentView you will probably need to use vue as well, with button @click="currentView('posts')".

Other way you can do it is using bus to emit the value, like

var bus = new Vue();
$(document).ready(function(){
    bus.$emit('my-component');
})

but not sure if that what you want

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.