avatar

吱托邦

面包会有的,牛奶也会有的,一切都会有的

0%

vue中实现可编辑div组件,并通过v-model双向绑定数据

最近在项目中的很多地方需要使用到输入框,以前我自己包括绝大多数人都会想到直接使用input吧,比如vuejs项目配合elementui的el-input组件也比较好用。但是当前的这个项目却不适合使用el-input,甚至连原生的input也不适合使用,为什么呢?第一是输入框原本的样式不适合这个项目,修改el-input和input的样式都有点麻烦;其次最大的问题在于,input很难随着输入内容的增加减少而相应的改变宽度,input一般是固定了某种宽度的,它不能做到fit-content特性。

然而,我发现div的一些特性就很适合作为该项目的输入框使用,首先是因为div的样式很容易通过简单的css进行调整,其次是div可以自动根据输入内容的变化调整自己的宽度,这正是我们所需要的,也就是div自动适应输入的内容。可是div可以实现编辑功能吗,经过查找我们发现了contentEditable属性,只要使用了这个属性,div就变成可编辑的了,接下来就需要考虑如何包装div组件,并且如何实现v-model功能。
可编辑的div此时还不能做到数据双向绑定,因此他还不算是一个真正好用的输入框。要知道如果能在这个可编辑的div上实现v-model数据双向绑定,那么他才是真正的好用,而且也真正实现了组件的可复用性。最终,经过研究vuejs(该项目使用的是vue3)文档内容,实现了div的数据双向绑定v-model功能,下面是该自定义可编辑div组件的核心代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<template>
<div class="editableDiv" contenteditable="true" :data-placeholder="placeholder" @input="divInput">{{ myTitle }}</div>
</template>

<script>
export default {
name: 'MyEditableDiv',
props: {
modelValue: {
type: String,
default: undefined,
},
placeholder: {
type: String,
default: undefined,
}
},
data() {
return {

}
},
computed:{
myTitle(){
return this.modelValue
}
},
methods: {
divInput(ev) {
this.$emit('update:modelValue', ev.target.innerText)
},
}
}
</script>

<style scoped>
.editableDiv{
outline: none;
padding: 0 2px;
word-break: break-word;
min-width: 20px;
}
div:empty::before {
content: attr(data-placeholder);
}
</style>

该自定义可编辑div的名字为MyEditableDiv,并且通过data-placeholder和相应的css代码,实现了div的placeholder功能。该组件实现v-model数据双向绑定的原理为:从外界将名为modelValue的prop传到组件内,这里需要注意的是,modelValue是vue默认的实现v-model的名称(具体参考vue文档,里面有很详细说明);接下来如果div的内容变化了,就会触发div的input事件,input事件会触发this.$emit('update:modelValue', ev.target.innerText),将div中的输入值传输到组件外界绑定的变量中;此时,当外界绑定的变量值变化之后,通过组件内的计算属性,将改变传递到myTitle变量,至此就彻底实现了该div的数据双向绑定。我们在调用该div时,可以像el-input这类组件一样,直接使用v-model绑定数据变量即可非常方便的使用了。vue中实现可编辑div组件,并通过v-model双向绑定数据

但是目前该组件还有一个比较烦人的问题,每次输入一个字符之后,光标都会跳到最前面,这是由于监听了input事件,并给div直接赋值导致的。如果想解决这个问题,可以将input事件换成blur事件,这样div就不会出现光标跳到最前的问题了,主要是根据具体的业务需求来改造合适的组件。网络上也有很多方法,可以每次都将光标自动移到div的最后一个字符后面去,也同样能解决问题。

*该文章原创并发表于吱托邦网站,未经允许禁止转载!

文章标题:vue中实现可编辑div组件,并通过v-model双向绑定数据
文章链接:https://www.lovebykin.com/3763505891/
版权声明:若无特殊标注,文章皆由吱托邦原创,转载请注明出处。
赞赏文章:如果文章有帮助,可以通过下方赞赏码对吱托邦进行鼓励。