html 双向绑定组件,contenteditable联合v-html实现数据双向绑定的vue组件
先看最终实现的demo效果图:
(1)上面看似文本域的大框是通过给div添加contenteditable=true属性实现的Vue组件DivEditable.vue;
(2)下面的输入框是父组件中与DivEditable绑定相同变量的输入框,用于展示数据的双向绑定效果;
(3)按钮实现绑定变量的赋值操作;
(4)DivEditable的blur事件可触发文本过滤或样式的变更等操作(专门留的组件接口);
可以看到,DivEditable中值的改变会影响输入框中的值,同样的,输入框中值改变也会影响DivEditable中的值,通过按钮给绑定变量赋值同时触发了输入框及DivEditable中值的改变。
1、contenteditable属性
用于设置或返回元素的内容是否可编辑。:
疑问:这时你可以能会想,这么麻烦,怎么不直接使用可编辑元素?比如我们最常见的有input、textarea。
解答:但如果你想要在输入的内容中加入html代码,并且还要正常渲染,就要与v-html结合使用,所以我们只能采用不可编辑元素并为其添加contenteditable为true的属性。
2、怎么实现DivEditable数据的双向绑定
犯傻1:一开始我天真的以为v-html与v-model一样,变量赋值后自带双向绑定,=.=事实证明还是太嫩;
犯傻2:于是我想那我再加一个v-model不就完事儿了,结果证明还是太嫩,浏览器直接报错'v-model' directives aren't supported on
最终只能自己上了:
(1)首先可以通过@input事件监听到输入值的变化,此时就可以获取到变化后的值并将其传递给父组件;
(2)虽然div不能添加v-model,但是在父组件中我调用DivEditable时却可以为其添加v-model;
(3)v-model中传入的值可以在子组件prop中获取的到;
(4)这时你再监听获取到的prop值,并将该值赋值给子组件中的v-html参数,双向绑定就搞定啦。
这里引入Vue官方描述:
自定义组件的v-model:一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,v-model的值将会传入子组件中的prop。
DivEditable.vue组件源码(可以结合我上面的步骤描述看会更容易理解):
exportdefault{
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')
}
}
}
.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;
}}
}
重点说明一下isChange参数的作用:
你可以先尝试拿掉它以及相关逻辑,看看最终会出现什么效果(输入一个字母光标就跑到前面去了,并且输入不了中文);
分析一下原因:
(1)通过打断点可以看到,当你输入的时候触发input事件,提交值给父组件中的v-model;
(2)但因为在子组件中又监听了v-model的值,所以整体形成了闭环;
(3)还需要重点说明的是光标问题,contenteditable与v-html所在的元素值的改变如果不是通过输入而是通过赋值实现,光标就会跑到最前面;
所以以输入中文为例,你刚打了一个字母,立马就触发了监听与变动,光标移到最前面,自然无法完成整个正常的输入。
解决办法:
只有当blur的时候再做赋值操作(isChange为true),focus状态下不做赋值(isChange为false);
至于初始为true的原因是在父组件中直接给绑定的变量赋值时子组件中还是需要触发赋值的(isChange为true);
除此之外,我还为组件提供了一个blur事件的函数接口,你可以做一些数据的过滤或者样式的变更,例如我demo中要高亮标签。
3、父组件调用
直接上源码:
改变值
html 双向绑定组件,contenteditable联合v-html实现数据双向绑定的vue组件相关推荐
- 利用ASP.NET MVC 的默认类型绑定器---将Jquery datatables中的数据强类型绑定到实体类中
背景描述: 本文参考资料:https://blog.csdn.net/honantic/article/details/45913403 阅读了上述博文后对我产生了启发,在ASP.NET MVC 5中 ...
- 巧用v-model实现组件间数据双向绑定
在vue的开发中,我们常常会构造自定义组件,多个自定义组件组合至父级组件中,父子组件的通信方式基本是:父组件通过Prop向子组件传递数据. <!-- 父组件 --> <templat ...
- Vue的数据双向绑定和Object.defineProperty()
Vue是前端三大框架之一,也被很多人指责抄袭,说他的两个核心功能,一个数据双向绑定,一个组件化分别抄袭angular的数据双向绑定和react的组件化思想,咱们今天就不谈这种大是大非,当然我也没到达那 ...
- Vue数据双向绑定原理(vue2向vue3的过渡)
众所周知,Vue的两大重要概念: 数据驱动 组件系统 接下来我们浅析数据双向绑定的原理 一.vue2 1.认识defineProperty vue2中的双向绑定是基于defineProperty的ge ...
- vue组件化开发实践
前言 公司目前制作一个H5活动,特别是有一定统一结构的活动,都要码一个重复的轮子.后来接到一个基于模板的活动设计系统的需求,便有了一下的内容.首先会对使用Vue进行开发的一些前期需要的技术储备进行简单 ...
- 【Vue知识点- No4.】vue组件、组件通信、Todo案例
知识点自测 this指向 let obj = {fn: function(){// this指向此函数的调用者},fn () {// this指向当前函数的调用者 (如果都是在vue里, this指向 ...
- Vue 组件 全家桶
Vue是一个构建数据驱动的 web 界面的渐进式框架.Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件特别整理了常用的vue插件,这里对vue插件汇总,提供vue组件 ...
- 前端架构之路:数据驱动型组件-HeyUI,一个新型的VUE组件库
什么是数据驱动型组件? 其实,目前来说,也只有HEYUI组件库是这种方式的尝试者,这也是我在设计组件库的过程中,慢慢思考的成果. 所以,关于这一种定义,还没有人运用过. 当然,这也是HEYUI区别于其 ...
- Vue组件通信以及.sync修饰符的使用
文章目录 前言 一.Vue的组件通信方式 1.1 props/$emit 1.2 Vuex 二.Vue的.sync修饰符 2.1 父组件向子组件传递数据 2.2 子组件使用props接收父组件的数据 ...
最新文章
- SpringCloud系列——Zuul 动态路由
- python sum 数组原理_Python - Sum 4D数组
- 单件模式(Singleton Pattern)(转自TerryLee)
- 排序(冒泡、选择、插入、希尔、快排、堆排、归并)
- mac连接局域网mysql_MySQL for Mac 安装和基本操作
- 判断当前浏览器是不是微信浏览器
- python必背入门代码-python学习必备知识汇总
- [数据仓库]Bill Inmon和Ralph Kimball方法论
- 利用github for windows 工具将本地的内容同步到github上
- 【转载】【SQL】Sql Server Management Studio 18 打开闪退问题
- swarm 集群配置
- SVM多分类器的实现
- c语言 停车管理系统
- 论文笔记 Inverting Visual Representations with Convolutional Networks
- 服务器raid5数据恢复成功案例,磁盘阵列数据恢复方法
- 牛电科技电动车 出行的最佳选择
- Python机器学习iris数据集预处理和模型训练
- HTML网页制作入门
- 修改hosts不管用。为什么修改127.0.0.1指向的域名,访问域名却弹出别的网站
- T6客户档案-供应商-存货名称不能录入空格--sql 怎么去掉最后一个字符