Vue: 一个简单的Vue2.0 v-model双向数据绑定的实现,含源代码,小白也能看懂
首先说一下原理吧
View层(dom元素)的变动如何响应到Model层(Js变量)呢? 通过监听元素的input事件来动态的改变js变量的值,实际上不是改变的js变量的值,而是改变的js变量的getter的返回值
Model层(Js变量)的变动如何响应到View层(dom元素)呢?通过Object.defineProperty API的set回调方法可以劫持JS变量设置的新值newVal,然后将新值newVal设置给dom元素。
定义我们的view层
<input type="text" v-model="msg"><br>
<input type="text" v-model="msg"><br>
<input type="text" v-model="name">
定义我们的model代码
let data = {
msg: 'hello',
name: ''
}
定义我们的核心代码双向数据绑定
// 用户存放状态更改的新值
let reflect = {};
// 用于存放状态到dom元素的映射 也就是key是data里面的属性,value存的是数组domArr,domArr存放的是v-model等于key的元素
let deep = {};
// 查询到所有的含有v-modle属性的dom元素
document.querySelectorAll("[v-model]").forEach(item => {
// 获得dom元素的v-model的值
let model = item.getAttribute("v-model");
// 如果如果值所对应的映射数组为空的话 就初始化
deep[model] = deep[model] || [];
// 绑定状态和dom元素的映射关系
deep[model].push(item)
// 初始化dom元素的值 和 状态get的值
reflect[model] = item.value = data[model];
//监听dom元素的input事件
item.addEventListener('input', function(){
// 将dom元素的新值赋值给data中定义的状态
data[model] = item.value;
},false)
})
// 循环遍历所有状态
for(let [key, val] of Object.entries(data)){
// 通过Object.defineProperty来实现监听
Object.defineProperty(data, key, {
// 劫持状态更新的新值
set(newVal){
// 将更新的新值设置给get的返回值
reflect[key] = newVal;
// 循环将更新的新值设置给关联的的dom元素
deep[key] && deep[key].forEach(item => {
item.value = newVal;
})
return newVal;
},
// 返回状态的新值
get(){
return reflect[key];
}
})
}
此时,无论是改变input的值,还是改变data里面定义的状态,数据都会向另一端同步。
PS:这只是简单的实现了一下v-model,与Vue 2中的实现还是有一些差异的,原理都是相同的。
Vue: 一个简单的Vue2.0 v-model双向数据绑定的实现,含源代码,小白也能看懂的更多相关文章
- 小白也能看懂的Redis教学基础篇——做一个时间窗限流就是这么简单
不知道ZSet(有序集合)的看官们,可以翻阅我的上一篇文章: 小白也能看懂的REDIS教学基础篇--朋友面试被SKIPLIST跳跃表拦住了 书接上回,话说我朋友小A童鞋,终于面世通过加入了一家公司.这 ...
- vue3.0中的双向数据绑定方法
熟悉vue的人都知道在vue2.x之前都是使用object.defineProperty来实现双向数据绑定的 而在vue3.0中这个方法被取代了 1. 为什么要替换Object.definePrope ...
- 超简单的vue2.0分页组件
1.组件代码 <template> <div class="pagination_comment_style" style="width: 100%;o ...
- html一个页面链接携带参数跳转另一个页面基于vue2.0的element框架
来给生活比个耶! 1.按钮 <el-button @click="albumList(scope.row.id)" size="mini" type=&q ...
- 小白都能看懂的vue中各种通信传值方式,附带详细代码
1.路由通信传值 路由通信是通过路由跳转用query把参数带过去,也是vue常用的通信手段. 例子: 创建并在路由注册一个组件Head <template> <div id=&quo ...
- 【紧急】Log4j又发新版2.17.0,只有彻底搞懂漏洞原因,才能以不变应万变,小白也能看懂
1 事件背景 经过一周时间的Log4j2 RCE事件的发酵,事情也变也越来越复杂和有趣,就连 Log4j 官方紧急发布了 2.15.0 版本之后没有过多久,又发声明说 2.15.0 版本也没有完全解决 ...
- Angular2.0 基础:双向数据绑定 [(ngModel)]
在属性绑定中,值从模型到屏幕上的目标属性 (property). 通过把属性名括在方括号中来标记出目标属性,[]. 这是从模型到视图的单向数据绑定. 而在事件绑定中,值是从屏幕上的目标属性 到 mod ...
- centos7安装puppet详细教程(简单易懂,小白也可以看懂的教程)
简介: Puppet是一种linux.unix平台的集中配置管理系统,使用ruby语言,可配置文件.用户.cron任务.软件包.系统服务等.Puppet把这些系统实体称之为资源,它的设计目标是简化对这 ...
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十五 ║Vue基础:JS面向对象&字面量& this字
缘起 书接上文<从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十四 ║ VUE 计划书 & 我的前后端开发简史>,昨天咱们说到了以我的经历说明的web开发经历的 ...
随机推荐
- c++ fstream feekg讨论
#include <iostream> #include <fstream> using namespace std; int main() { std::ifstream f ...
- 初步认识HCIA,什么是计算机网络,拓扑,网络的发展,交换机,路由器,IP,光纤,带宽,广播,ARP......
HCIA ---- 华为认证初级网络工程师 云技术 --- 云存储 云计算 计算机技术 : --- 抽象语言 -- 电线号的转换 抽象语言 -- 编码 ---- 应用层 编码 --- 二进制 -- ...
- NX Open显示符号(UF_DISP_display_temporary_point)
UF_DISP_display_temporary_point 使用方法: 1 Dim x As Double = 0, y As Double = 0, z As Double = 0 2 3 Di ...
- 款阿里开源的 Java 诊断工具Arthas
Arthas是什么鬼? Arthas是一款阿里巴巴开源的 Java 线上诊断工具,功能非常强大,可以解决很多线上不方便解决的问题. Arthas诊断使用的是命令行交互模式,支持JDK6+,Linux. ...
- JavaScript03
类型转换和运算符 typeof函数 检测数据类型,可以使用以下两种调用的方式: typeof 变量或表达式 typeof(变量或表达式) var n="asda"; console ...
- 高斯消元de小板几
感觉就是模拟解方程,还比手动解方程笨一些.... 但是大数据的话,他毕竟比我解得快多了.... 1 inline int Gauss(int n){ 2 int cnt=1;//真实到达的行列式行数 ...
- [火星补锅] 非确定性有穷状态决策自动机练习题Vol.1 T3 第K大区间 题解
前言: 老火星人了 解析: 很妙的二分题.如果没想到二分答案.. 很容易想到尝试用双指针扫一下,看看能不能统计答案. 首先,tail指针右移时很好处理,因为tail指针右移对区间最大值的影响之可能作用 ...
- 数据治理之元数据管理的利器——Atlas入门宝典
随着数字化转型的工作推进,数据治理的工作已经被越来越多的公司提上了日程.作为Hadoop生态最紧密的元数据管理与发现工具,Atlas在其中扮演着重要的位置.但是其官方文档不是很丰富,也不够详细.所以整 ...
- 算法:N-皇后问题
一.八皇后问题 八皇后问题是一个以国际象棋为背景的问题:如何能够在8 × 8 的国际象棋棋盘上放置八个皇后(Queen),使得任何一个皇后都无法直接吃掉其他的皇后.为了达到此目的,任两个皇后都不能处于 ...
- 记一次 Java 导出大批量 Excel 优化
常用的excel导出方案,详情见Spring Boot 入门(十二):报表导出,对比poi.jxl和esayExcel的效率,其中jxl.esayEscel 底层都是基于 poi,它们仅仅是对 poi ...