2

We have a web app that uses Vue as the front end framework.

This web app has a text editor, and as part of the functionality of the text editor, it will add custom HTML to the editable area (a contenteditable div.)

The editor can add HTML which is a Vue component but I need some way of compiling the Vue component before/after inserting it into the DOM.

For example, let's assume we have a contenteditable div like so:

<div contenteditable="true">
    <p>Some text</p>
</div>

Now, on a user action, after the <p> tag, the editor will insert an Vue component.

<div contenteditable="true">
    <p>Some text</p>
    <custom-gallery></custom-gallery>
</div>

<custom-gallery></custom-gallery> is a Vue component. How do I 'execute' this component so it renders the HTML, event handlers etc?

One idea I had is to insert an element like:

<div contenteditable="true">
    <p>Some text</p>
    <div class="custom-gallery"></div>
</div>

and then execute this:

import Vue from 'vue'
import CustomGallery from './path/to/components/CustomGallery.vue'

new Vue({
    el: document.querySelector(".custom-gallery"),
    render: h => h(CustomGallery)
})

Would that be the best way? Will that work if it's already inside a Vue application?

3
  • You can't init a Vue instance inside another Vue instance. Perhaps it should be a component Commented Mar 26, 2018 at 5:16
  • Have you ever tried creating another Vue instance or component and getting its innerHtml? Commented Mar 26, 2018 at 6:02
  • Were you able to find a solution to this other than instantiating a new vue app everytime the component is added? Commented Nov 22, 2022 at 18:02

2 Answers 2

2

After you insert the Vue component into the DOM, instantiate the Vue instance:

$('#ControlContainer').append("<vueComponent id='component1'></vueComponent>");

var vmComponent = new Vue({
            el: '#component1',
            mounted: function () {
            }
        });
Sign up to request clarification or add additional context in comments.

Comments

0

I suggest you simply use a dynamic component and have it already in your contenteditable div when you first render your page.

<div contenteditable="true">
    <component :is="myComponent"></component>
</div>

myComponent could be a function that you can pass the component name to and even switch it out dynamically with different components. However in your case you can just have it start out as prop with a false or null value and then when you wish to initialize the gallery component call a function to set the name.

data:{
   component: false,
},
   methods: {
     setComponent(){
        this.component = 'custom-gallery';
}

Here is a jfiddle with a basic working example https://jsfiddle.net/skribe/3d15L39t/7/

More about dynamic components here https://v2.vuejs.org/v2/guide/components.html#Dynamic-Components

3 Comments

Thanks. I think this will suffer the same problem I was describing. Because <component></component> will be inserted dynamically into the DOM, Vue won't compile/execute it. For example, the user may click a button to insert a <custom-gallery></custom-gallery>, but something needs to tell Vue that this has been inserted in the DOM, and to compile it.
Also, the user may insert multiple of these custom components, so it's not really possible to have them there from the start.
Your question is confusing then because you say, "... it will add custom HTML to the editable area," and "...let's assume we have a contenteditable div like so." Which seems to indicate the contenteditable div will already be defined in the html form the start.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.