【发布时间】:2019-12-29 18:07:46
【问题描述】:
我正在尝试将 Codemirror 实例嵌入为 Vue 组件,类似于在此 project 中完成的操作。但是,不是在父级中返回 Codemirror 实例的模板
<div class="vue-codemirror" :class="{ merge }">
<!-- Textarea will be replaced by Codemirror instance. -->
<textarea ref="textarea" :name="name" :placeholder="placeholder" v-else>
</textarea>
</div>
我只是想单独返回 Codemirror 实例。我不能简单地删除父div并拥有的原因
<!-- Textarea will be replaced by Codemirror instance. -->
<textarea ref="textarea" :name="name" :placeholder="placeholder" v-else>
</textarea>
是因为替换textarea的方法CodeMirror.fromTextArea()需要textarea有一个parentNode。否则会遇到空错误。
幸运的是,有一种方法可以在不使用文本区域的情况下创建 Codemirror 实例,CodeMirror()。这个实例有一个函数getWrapperElement(),它返回DOM节点:
<div class="CodeMirror cm-s-default">
...
</div>
我想使用 Vue template/render 函数输出与 Codemirror 实例相关的特定 DOM 节点。我创建实例的当前方式是在组件data 对象中对其进行初始化。
data: function () {
// Create a CodeMirror instance.
let cm = new CodeMirror(null, {
...
})
return {
// Define a CodeMirror instance for each CodeBlockView.
cm : cm,
...
}
},
更新 1:我找到了一种方法来做到这一点,尽管它非常像黑客。我们使用通过 render 传入的 createElement 函数,并将我们要渲染的 DOM 节点的 innerHTML 传递给数据对象参数。 它似乎在视觉上工作,但 CodeMirror 实例不可编辑。
render: function (createElement) {
return createElement('div', {
class: this.dom.classList.value,
domProps: {innerHTML: this.dom.innerHTML}
})
}
更新 2:然而,这并没有传入实际的 DOM 节点,而只是浅层地复制它;这带来了一个问题,因为它不允许它是可编辑的,也不允许附加一个 CodeMirror 实例。
【问题讨论】:
-
看来您需要隐藏 textarea 而不是完全删除:
<textarea ref="textarea" :name="name" :placeholder="placeholder" v-show="!merge"></textarea> -
textarea 的删除是在 CodeMirror 库中完成的;我宁愿不必更改它的原始代码。有没有办法使用
getWrapperElement中的DOM节点作为模板来渲染? -
使用渲染是一种错误的方式来做你想做的事。更喜欢使用 ref 而不是 vuejs.org/v2/api/#ref
-
现在我有
template:<textarea ref="textarea"></textarea>,CodeMirror的实例化方法在mounted。根据我在vuejs.org/v2/guide/instance.html 上阅读的内容,似乎this.$refs.textarea.parentNode在挂载时不应该为空,因为this.$refs.textarea应该在实际的DOM 节点上。出于某种原因,这导致mounted和created之间的连续循环,导致我的浏览器窗口崩溃。
标签: vue.js codemirror