光标自动定位到起始位置 contenteditable="true" ,v-html绑定内容,div可编辑时,光标移到最前面
出现这个问题原因:
(1)通过打断点可以看到,当你输入的时候触发input事件,提交值给父组件中的v-model;
(2)但因为在子组件中又监听了v-model的值,所以整体形成了闭环;
(3)还需要重点说明的是光标问题,contenteditable与v-html所在的元素值的改变如果不是通过输入而是通过赋值实现,光标就会跑到最前面;
所以以输入中文为例,你刚打了一个字母,立马就触发了监听与变动,光标移到最前面,自然无法完成整个正常的输入。
解决办法:
只有当blur的时候再做赋值操作(isChange为true),focus状态下不做赋值(isChange为false);
至于初始为true的原因是在父组件中直接给绑定的变量赋值时子组件中还是需要触发赋值的(isChange为true);
<template>
<div
class="div-editable"
contenteditable="true"
v-html="innerText"
@input="changeText"
@focus="isChange = false"
@blur="blurFunc"></div>
</template>
<script>
export default {
name: 'DivEditable',
props: {
value: {
type: String,
default: ''
}
},
data() {
return {
innerText: this.value,
isChange: true
}
},
watch: {
value() {
if (this.isChange) {
this.innerText = this.value
}
}
},
methods: {
changeText() {
this.$emit('input', this.$el.innerHTML)
},
blurFunc() {
this.isChange = true
this.$emit('blurFunc')
}
}
}
</script>
<style lang="scss">
.div-editable{
width: 100%;
height: 100%;
overflow-y: auto;
word-break: break-all;
outline: none;
user-select: text;
white-space: pre-wrap;
text-align: left;
&[contenteditable=true]{
user-modify: read-write-plaintext-only;
&:empty:before {
content: attr(placeholder);
display: block;
color: #ccc;
}
}
}
</style>
蓦然、回首,那人就在灯火阑珊处