I am trying to embed a Codemirror instance as a Vue component, similar to what was accomplished in this project. However, instead of returning a template of the Codemirror instance inside of a parent
<div class="vue-codemirror" :class="{ merge }">
<!-- Textarea will be replaced by Codemirror instance. -->
<textarea ref="textarea" :name="name" :placeholder="placeholder" v-else>
</textarea>
</div>
I am simplying trying to return the Codemirror instance alone. The reason why I can't simply remove the parent div and have
<!-- Textarea will be replaced by Codemirror instance. -->
<textarea ref="textarea" :name="name" :placeholder="placeholder" v-else>
</textarea>
is because the method to replace the textarea, CodeMirror.fromTextArea(), requires the textarea to have a parentNode. Otherwise, a null error will be encountered.
Luckily, there is a way to create a Codemirror instance without using a textarea at all, CodeMirror(). This instance has a function getWrapperElement() that returns the DOM node:
<div class="CodeMirror cm-s-default">
...
</div>
I want to output this specific DOM node relating to Codemirror instance using the Vue template/render function. The current way I'm creating the instance is by initializing it in the component data object.
data: function () {
// Create a CodeMirror instance.
let cm = new CodeMirror(null, {
...
})
return {
// Define a CodeMirror instance for each CodeBlockView.
cm : cm,
...
}
},
Update 1: I have found one way to do this, albeit very hacker-ish. We use the createElement function that is passed in with render and pass into the data object argument the innerHTML of DOM node we want to render. It seems to be working visually but the CodeMirror instance isn't editable.
render: function (createElement) {
return createElement('div', {
class: this.dom.classList.value,
domProps: {innerHTML: this.dom.innerHTML}
})
}
Update 2: However, this doesn't pass in the actual DOM node rather it only shallowly copies it; this presents a problem as it doesn't allow it to be editable nor have a CodeMirror instance attached.
asked Mar 01 '26 04:03
You cannot change the template anymore after the component has been created. It's not a property of the component but a parameter that is passed to the constructor as far as I know.
Hence, you would need to create the CodeMirror instance before the component is created and inject it.
However, I fail to see the problem with a wrapping component, could you explain the why?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With