首先说一下原理吧

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双向数据绑定的实现,含源代码,小白也能看懂的更多相关文章

  1. 小白也能看懂的Redis教学基础篇——做一个时间窗限流就是这么简单

    不知道ZSet(有序集合)的看官们,可以翻阅我的上一篇文章: 小白也能看懂的REDIS教学基础篇--朋友面试被SKIPLIST跳跃表拦住了 书接上回,话说我朋友小A童鞋,终于面世通过加入了一家公司.这 ...

  2. vue3.0中的双向数据绑定方法

    熟悉vue的人都知道在vue2.x之前都是使用object.defineProperty来实现双向数据绑定的 而在vue3.0中这个方法被取代了 1. 为什么要替换Object.definePrope ...

  3. 超简单的vue2.0分页组件

    1.组件代码 <template> <div class="pagination_comment_style" style="width: 100%;o ...

  4. html一个页面链接携带参数跳转另一个页面基于vue2.0的element框架

    来给生活比个耶! 1.按钮 <el-button @click="albumList(scope.row.id)" size="mini" type=&q ...

  5. 小白都能看懂的vue中各种通信传值方式,附带详细代码

    1.路由通信传值 路由通信是通过路由跳转用query把参数带过去,也是vue常用的通信手段. 例子: 创建并在路由注册一个组件Head <template> <div id=&quo ...

  6. 【紧急】Log4j又发新版2.17.0,只有彻底搞懂漏洞原因,才能以不变应万变,小白也能看懂

    1 事件背景 经过一周时间的Log4j2 RCE事件的发酵,事情也变也越来越复杂和有趣,就连 Log4j 官方紧急发布了 2.15.0 版本之后没有过多久,又发声明说 2.15.0 版本也没有完全解决 ...

  7. Angular2.0 基础:双向数据绑定 [(ngModel)]

    在属性绑定中,值从模型到屏幕上的目标属性 (property). 通过把属性名括在方括号中来标记出目标属性,[]. 这是从模型到视图的单向数据绑定. 而在事件绑定中,值是从屏幕上的目标属性 到 mod ...

  8. centos7安装puppet详细教程(简单易懂,小白也可以看懂的教程)

    简介: Puppet是一种linux.unix平台的集中配置管理系统,使用ruby语言,可配置文件.用户.cron任务.软件包.系统服务等.Puppet把这些系统实体称之为资源,它的设计目标是简化对这 ...

  9. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十五 ║Vue基础:JS面向对象&字面量& this字

    缘起 书接上文<从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 十四 ║ VUE 计划书 & 我的前后端开发简史>,昨天咱们说到了以我的经历说明的web开发经历的 ...

随机推荐

  1. 题解 Weak in the Middle

    题目传送门 Description 有一个长度为 \(n\) 的序列 \(a_{1,2,...,n}\) ,每次可以删掉 \(a_i\),当 \(\min(a_{i-1},a_{i+1})>a_ ...

  2. 洛谷3203 弹飞绵羊(LCT)

    据说这个题当年的正解是分块qwq 根据题目所说,对于题目中的弹力系数,就相当于一条边,那么对于"跳出去"这个限制,我们可以选择建造一个新点\(n+1\)表示结束,那么每次,求一个点 ...

  3. [NOIP2013 提高组] 华容道 P1979 洛谷

    [NOIP2013 提高组] 华容道 P1979 洛谷 强烈推荐,更好的阅读体验 经典题目:spfa+bfs+转化 题目大意: 给出一个01网格图,和点坐标x,y空格坐标a,b,目标位置tx,ty要求 ...

  4. 2020.5.16-ICPC Central Europe Regional Contest 2019

    A. ABB #include <bits/stdc++.h> using namespace std; #define PB push_back #define ZERO (1e-10) ...

  5. Ysoserial Commons Collections7分析

    Ysoserial Commons Collections7分析 写在前面 CommonsCollections Gadget Chains CommonsCollection Version JDK ...

  6. 【UE4】GAMES101 图形学作业0:矩阵初识

    作业描述 给定一个点P=(2,1), 将该点绕原点先逆时针旋转45◦,再平移(1,2), 计算出变换后点的坐标(要求用齐次坐标进行计算). UE4 知识点 主要矩阵 FMatrix FBasisVec ...

  7. springBoot服务整合线程池ThreadPoolTaskExecutor与@Async详解使用

    ThreadPoolExecutor:=======这个是java自己实现的线程池执行类,基本上创建线程池都是通过这个类进行的创建.ThreadPoolTaskExecutor:========这个是 ...

  8. Seata的一些概念

    Seata的一些概念 一.什么是seata 二.AT模式的介绍 1.前提条件 2.整体机制 3.读写隔离的实现 1.写隔离 2.读隔离 三.事务分组 1.事务分组是什么? 2.通过事务分组如何找到后端 ...

  9. 利用Microsoft Graph开发微软的Exchange Calendar会议、Team

    Microsoft Graph是什么? Microsoft Graph 是 Microsoft 365 中通往数据和智能的网关. 它提供统一的可编程模型,可用于访问 Microsoft 365.Win ...

  10. SVN查看项目修改记录及修改内容

    工具/原料 svn 一,查看修改记录 1 选择要查看的文件夹,打开之后在空白的地方右键. 2 选择svn里面的"查看日志".show_Log 3 在弹出的日志框里,可以看到,你可以 ...