思路:
1.创建模拟场景

<div id="app"><input type="text" id="input" v-model="value">{{ value }}
</div>
var vm = new Vue({el: 'app',data() {return {value: 'hello, world'}}
})

2.初始化vue函数

function Vue(options) {const { el, data } = options;this.el = document.getElementById(el)this.data = data()
}

3.生成虚拟dom

function Vue(options) {const { el, data } = options;this.el = document.getElementById(el)this.data = data()var dom = nodeToFragment(this.el, this)this.el.appendChild(dom)
}function nodeToFragment(node, vm) {var flag = document.createDocumentFragment()var child;while (child = node.firstChild) {//}return flag
}

4.数据劫持

function observer(obj, vm) {Object.keys(obj).forEach(key => {defineReactive(vm, key, obj[key])})
}function defineReactive(vm, key, value) {Object.defineProperty(vm, key, {get() {return value},set(newValue) {value = newValue}})
}

5.页面初始化

function compare(node, vm) {var reg = /\{\{(.*)\}\}/if (node.nodeType === 1) {var attrs = node.attributes;for (let i = 0; i < attrs.length; i ++) {if (attrs[i].nodeName === 'v-model') {var name = attrs[i].nodeValue;node.addEventListener('input', function(e) {vm[name] = e.target.value;}, false)node.removeAttribute('v-model')node.value = vm[name]}}}if (node.nodeType === 3) {if (reg.test(node.nodeValue)) {let name = RegExp.$1;name = name.trim()node.nodeValue = vm[name]}}
}

6.订阅-----观察者模式

function Watcher(vm, node, name, nodeType) {Dep.target = thisthis.node = nodethis.name = namethis.nodeType = nodeTypethis.vm = vmthis.update()Dep.target = null
}Watcher.prototype = {update: function () {this.get()if (this.nodeType === 'input') {this.node.value = this.value}if (this.nodeType === 'text') {this.node.nodeValue = this.value}},get: function () {this.value = this.vm[this.name]}
}
function Dep() {this.subs = []
}Dep.prototype = {addSub: function (sub) {this.subs.push(sub)},notify: function () {this.subs.forEach(sub => {sub.update()})}
}

7.代码汇总

function Vue(options) {const { el, data } = options;this.el = document.getElementById(el)this.data = data()observer(this.data, this)var dom = nodeToFragment(this.el, this)this.el.appendChild(dom)
}function observer(obj, vm) {Object.keys(obj).forEach(key => {defineReactive(vm, key, obj[key])})
}// 数据劫持
function defineReactive(vm, key, value) {var dep = new Dep()Object.defineProperty(vm, key, {get() {if (Dep.target) {dep.addSub(Dep.target)}return value},set(newValue) {value = newValuedep.notify()}})
}function nodeToFragment(node, vm) {var flag = document.createDocumentFragment()var child;while (child = node.firstChild) {compare(child, vm)flag.appendChild(child)}return flag
}function compare(node, vm) {var reg = /\{\{(.*)\}\}/if (node.nodeType === 1) {var attrs = node.attributes;for (let i = 0; i < attrs.length; i++) {if (attrs[i].nodeName === 'v-model') {var name = attrs[i].nodeValue;node.addEventListener('input', function (e) {vm[name] = e.target.value;}, false)node.value = vm[name]node.removeAttribute('v-model')new Watcher(vm, node, name, 'input')}}}if (node.nodeType === 3) {if (reg.test(node.nodeValue)) {let name = RegExp.$1;name = name.trim()node.nodeValue = vm[name]new Watcher(vm, node, name, 'text')}}
}function Watcher(vm, node, name, nodeType) {Dep.target = thisthis.node = nodethis.name = namethis.nodeType = nodeTypethis.vm = vmthis.update()Dep.target = null
}Watcher.prototype = {update: function () {this.get()if (this.nodeType === 'input') {this.node.value = this.value}if (this.nodeType === 'text') {this.node.nodeValue = this.value}},get: function () {this.value = this.vm[this.name]}
}
function Dep() {this.subs = []
}Dep.prototype = {addSub: function (sub) {this.subs.push(sub)},notify: function () {this.subs.forEach(sub => {sub.update()})}
}
var vm = new Vue({el: 'app',data() {return {value: 'hello, world'}}
})

简易vue2.0双向数据绑定相关推荐

  1. Vue2.x双向数据绑定

    1.vue双向绑定原理 vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给 ...

  2. 前端面试题 HTML5 CSS3(盒子模型、盒子水平垂直居中、经典布局) JS(闭包、深浅克隆、数据劫持和拦截) 算法(排序、去重、数组扁平化) Vue(双向数据绑定原理、通信方式)

    前端面试题 HTML5 相关面试题 CSS3 相关面试题 盒子模型 盒子水平垂直居中的方案 经典布局方案 圣杯布局 双飞翼布局 flex布局 定位方式布局 css实现三角形 JS 相关面试题 8种数据 ...

  3. React阶段 - React双向数据绑定原理

    React双向数据绑定原理 如果已经学过Vue,并且深入了解过Vue的双向数据绑定的话,就会明白 Vue 2.0 双向数据绑定的核心其实是通过Object.defineProperty来实现数据劫持和 ...

  4. 【Vue】双向数据绑定原理 vue2.0 与 vue3.0

    目录 一.什么是双向数据绑定? 二.双向数据绑定原理 vue2.0 三.Vue 3.0使用ES6的新特性porxy 四.思考 一.什么是双向数据绑定? vue是一个mvvm框架,即数据双向绑定,即当数 ...

  5. 手动实现vue2.0的双向数据绑定原理

    vue2.0的双向数据绑定原理(手动实现) 一句话概括:数据劫持(Object.defineProperty)+发布订阅模式 一.首先了解什么是发布订阅模式 二.new Vue()的时候做了什么? 一 ...

  6. 【Vue2.0学习】—数据绑定

    [Vue2.0学习]-数据绑定 <!DOCTYPE html> <html lang="en"><head><meta charset=& ...

  7. Vue2和Vue3的双向数据绑定原理

    目录 前言: vue2.x 是如何实现响应式系统的: defineProperty 的痛点: Object.defineProperty 代码的使用 Proxy 方法的理解 Proxy 代码的使用: ...

  8. 基于Vue2.0数据双向绑定原理-详解

    在线使用-线上测试-源码 //代码: <div id="app"><input v-model="name" type="text& ...

  9. vue2双向数据绑定原理

    先上文字描述: vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发 ...

最新文章

  1. 中国联邦学习「五大流派」
  2. SQL Server创建索引
  3. 三种方式实现观察者模式 及 Spring中的事件编程模型
  4. spring cloud面试
  5. 毕业论文 | 单相AC-DC变换电路(附源代码与电路设计图及器件清单)电子设计大赛
  6. c语言实现二分法_C语言实现二分法求解方程在区间内的根
  7. dataAdapter与dataSet和dataTable的填充
  8. python安装盒怎么打开_安装MySQL-python报错
  9. 硅谷公司:我们称他们为软件工程师,而非打工人
  10. 自己选择的路,不后悔
  11. android 9.0 开机动画,小米9开机动画安装器
  12. 谷歌邮箱登录服务器设置
  13. html多个div横向排列居中,多个div垂直居中横向排列的示例分析
  14. 汽车CAN总线 CAN2.0
  15. facebook 登陆失败 分享失败 原因汇总
  16. C盘清理(主要的大文件清理)
  17. plex插件显示无服务器,deepin 15.11 安装plex和插件
  18. 用python计算符号函数一元定积分和不定积分
  19. 微信小游戏《头脑王者》答题辅助脚本
  20. matlab | 程序运行时间

热门文章

  1. 前端企业微信服务商第三方应用开发详情流程2021-4-9
  2. 50页智慧校园解决方案[附下载]
  3. 谷粒商城RabbitMQ
  4. FPGA再入门——SPI IP核调用
  5. iSpring sdk运用ispring sdk下载
  6. 基于51单片机pwm调光护眼台灯智能检测光强光控灯设计proteus仿真原理图PCB
  7. fis3 html 变量替换,百度构建工具fis3常用命令及配置写法
  8. 插入排序(python)
  9. docker linux alpine 安装php扩展
  10. 电脑exe应用程序都用txt方式打开?