简易vue2.0双向数据绑定
思路:
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双向数据绑定相关推荐
- Vue2.x双向数据绑定
1.vue双向绑定原理 vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给 ...
- 前端面试题 HTML5 CSS3(盒子模型、盒子水平垂直居中、经典布局) JS(闭包、深浅克隆、数据劫持和拦截) 算法(排序、去重、数组扁平化) Vue(双向数据绑定原理、通信方式)
前端面试题 HTML5 相关面试题 CSS3 相关面试题 盒子模型 盒子水平垂直居中的方案 经典布局方案 圣杯布局 双飞翼布局 flex布局 定位方式布局 css实现三角形 JS 相关面试题 8种数据 ...
- React阶段 - React双向数据绑定原理
React双向数据绑定原理 如果已经学过Vue,并且深入了解过Vue的双向数据绑定的话,就会明白 Vue 2.0 双向数据绑定的核心其实是通过Object.defineProperty来实现数据劫持和 ...
- 【Vue】双向数据绑定原理 vue2.0 与 vue3.0
目录 一.什么是双向数据绑定? 二.双向数据绑定原理 vue2.0 三.Vue 3.0使用ES6的新特性porxy 四.思考 一.什么是双向数据绑定? vue是一个mvvm框架,即数据双向绑定,即当数 ...
- 手动实现vue2.0的双向数据绑定原理
vue2.0的双向数据绑定原理(手动实现) 一句话概括:数据劫持(Object.defineProperty)+发布订阅模式 一.首先了解什么是发布订阅模式 二.new Vue()的时候做了什么? 一 ...
- 【Vue2.0学习】—数据绑定
[Vue2.0学习]-数据绑定 <!DOCTYPE html> <html lang="en"><head><meta charset=& ...
- Vue2和Vue3的双向数据绑定原理
目录 前言: vue2.x 是如何实现响应式系统的: defineProperty 的痛点: Object.defineProperty 代码的使用 Proxy 方法的理解 Proxy 代码的使用: ...
- 基于Vue2.0数据双向绑定原理-详解
在线使用-线上测试-源码 //代码: <div id="app"><input v-model="name" type="text& ...
- vue2双向数据绑定原理
先上文字描述: vue.js是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发 ...
最新文章
- 中国联邦学习「五大流派」
- SQL Server创建索引
- 三种方式实现观察者模式 及 Spring中的事件编程模型
- spring cloud面试
- 毕业论文 | 单相AC-DC变换电路(附源代码与电路设计图及器件清单)电子设计大赛
- c语言实现二分法_C语言实现二分法求解方程在区间内的根
- dataAdapter与dataSet和dataTable的填充
- python安装盒怎么打开_安装MySQL-python报错
- 硅谷公司:我们称他们为软件工程师,而非打工人
- 自己选择的路,不后悔
- android 9.0 开机动画,小米9开机动画安装器
- 谷歌邮箱登录服务器设置
- html多个div横向排列居中,多个div垂直居中横向排列的示例分析
- 汽车CAN总线 CAN2.0
- facebook 登陆失败 分享失败 原因汇总
- C盘清理(主要的大文件清理)
- plex插件显示无服务器,deepin 15.11 安装plex和插件
- 用python计算符号函数一元定积分和不定积分
- 微信小游戏《头脑王者》答题辅助脚本
- matlab | 程序运行时间