Vue 2 contentEditable with v-model
[英] Vue 2 contentEditable with v-model
本文介绍了Vue 2 contentEditable with v-model的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试制作一个类似于 Medium 的文本编辑器.我正在使用内容可编辑的段落标签,并将每个项目存储在一个数组中,并使用 v-for 呈现每个项目.但是,我在使用 v-model 将文本与数组绑定时遇到了问题.似乎与 v-model 和 contenteditable 属性存在冲突.这是我的代码:
<button class="toolbar" v-on:click.prevent="stylize('bold')">粗体</button>
<div v-for="(value, index) in content"><p v-bind:id="'content-'+index" v-bind:ref="'content-'+index" v-model="content[index].value" v-on:keyup="emit_content($event)" v-on:keyup.delete="remove_content(index)" contenteditable></p>
在我的脚本中:
出口默认{数据() {返回 {内容:[{值:''}]}},方法: {风格化(风格){document.execCommand(style, false, null);},删除内容(索引){if(this.content.length > 1 && this.content[index].value.length == 0) {this.content.splice(index, 1);}}}}
我还没有在网上找到任何答案.
解决方案
我昨天想通了!解决了这个解决方案.我基本上只是通过更新任何可能的事件来手动跟踪我的 content
数组中的 innerHTML 并通过手动分配具有动态引用的相应元素重新渲染,例如content-0
, content-1
,... 效果很好:
<div id="编辑栏"><button class="toolbar" v-on:click.prevent="stylize('bold')">粗体</button>
<div><div v-for="(value, index) in content"><p v-bind:id="'content-'+index" class="content" v-bind:ref="'content-'+index" v-on:keydown.enter="prevent_nl($event)" v-on:keyup.enter="add_content(index)" v-on:keyup.delete="remove_content(index)" contenteditable></p>
模板><脚本>导出默认{数据() {返回 {内容: [{html: ''}]}},方法: {添加内容(索引){//附加到数组},删除内容(索引){//首先,检查一些边缘条件并从数组中删除//然后,通过ref更新每个元素的innerHTMLfor(var i = 0; i < this.content.length; i++) {this.$refs['content-'+i][0].innerHTML = this.content[i].html;}},风格化(风格){document.execCommand(style, false, null);for(var i = 0; i < this.content.length; i++) {this.content[i].html = this.$refs['content-'+i][0].innerHTML;}}}}
I'm trying to make a text editor similar to Medium. I'm using a content editable paragraph tag and store each item in an array and render each with v-for. However, I'm having problems with binding the text with the array using v-model. Seems like there's a conflict with v-model and the contenteditable property. Here's my code:
<div id="editbar">
<button class="toolbar" v-on:click.prevent="stylize('bold')">Bold</button>
</div>
<div v-for="(value, index) in content">
<p v-bind:id="'content-'+index" v-bind:ref="'content-'+index" v-model="content[index].value" v-on:keyup="emit_content($event)" v-on:keyup.delete="remove_content(index)" contenteditable></p>
</div>
and in my script:
export default {
data() {
return {
content: [{ value: ''}]
}
},
methods: {
stylize(style) {
document.execCommand(style, false, null);
},
remove_content(index) {
if(this.content.length > 1 && this.content[index].value.length == 0) {
this.content.splice(index, 1);
}
}
}
}
I haven't found any answers online for this.
解决方案
I figured it out yesterday! Settled on this solution. I basically just manually keep track of the innerHTML in my content
array by updating on any possible event and re-rendering by manually assigning the corresponding elements with dynamic refs e.g. content-0
, content-1
,... Works beautifully:
<template>
<div id="editbar">
<button class="toolbar" v-on:click.prevent="stylize('bold')">Bold</button>
</div>
<div>
<div v-for="(value, index) in content">
<p v-bind:id="'content-'+index" class="content" v-bind:ref="'content-'+index" v-on:keydown.enter="prevent_nl($event)" v-on:keyup.enter="add_content(index)" v-on:keyup.delete="remove_content(index)" contenteditable></p>
</div>
</div>
</template>
<script>
export default {
data() {
return {
content: [{
html: ''
}]
}
},
methods: {
add_content(index) {
//append to array
},
remove_content(index) {
//first, check some edge conditions and remove from array
//then, update innerHTML of each element by ref
for(var i = 0; i < this.content.length; i++) {
this.$refs['content-'+i][0].innerHTML = this.content[i].html;
}
},
stylize(style){
document.execCommand(style, false, null);
for(var i = 0; i < this.content.length; i++) {
this.content[i].html = this.$refs['content-'+i][0].innerHTML;
}
}
}
}
</script>
这篇关于Vue 2 contentEditable with v-model的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!