文档章节

Vue.js双向绑定的实现原理

别人说我名字很长
 别人说我名字很长
发布于 2016/12/10 00:08
字数 359
阅读 41
收藏 0
<!DOCTYPE html>
<html>
<head>
	<title>Vue.js双向绑定的实现原理</title>
</head>
<body>
<div id="app">
	<input type="text" v-model="text">
	{{ text }}
</div>

<script type="text/javascript">


//订阅者
function Dep(){
	this.subs = [];
}

Dep.prototype = {
	addSub:function(sub){
		this.subs.push(sub);
	},
	notify:function(){
		this.subs.forEach(function(sub){
			sub.update();
		});
	}
}

//发布者
function Watcher (vm, node, name) {
	Dep.target = this;	
	this.name = name;
	this.node = node;
	this.vm = vm;
	this.update();
	Dep.target = null;
}

Watcher.prototype = {
	update: function () {
		this.get();
		this.node.nodeValue = this.value;
	},
	// 获取data中的属性值
	get: function () {
		this.value = this.vm[this.name]; // 触发相应属性的get
	}
}


//对象访问器
function defineReactive(obj,key,val) {
	var dep = new Dep();
	Object.defineProperty(obj,key,{
		get:function(){
			// 添加订阅者watcher到主题对象Dep
			if(Dep.target)dep.addSub(Dep.target);
			console.log(dep.subs)
			return val;
		},
		set:function(newVal){
			if(newVal === val) return;
			val=newVal;
			//作为发布者发布通知
			dep.notify();
			console.log(val);
		}
	})
}

//观察者,观察data对象的变更,使用Object.defineProperty添加订阅者和发布通知
function observe(obj,vm){
	Object.keys(obj).forEach(function(key){
		defineReactive(vm,key,obj[key]);
	});
}

//编译方法
function compile(node,vm){
	var reg = /\{\{(.*)\}\}/;

	//节点类型为元素
	if(node.nodeType === 1){
		var attr = node.attributes;
		for(var i=0;i<attr.length;i++){
			if(attr[i].nodeName == 'v-model'){
				var name = attr[i].nodeValue;
				node.addEventListener('input',function(e){
					vm[name] = e.target.value;
				});
				node.value = vm[name];
				node.removeAttribute('v-model');
			}
		}
	}

	//节点类型为text
	if(node.nodeType ===3){
		if(reg.test(node.nodeValue)){
			var name = RegExp.$1;
			name = name.trim();
			new Watcher(vm,node,name);
		}
	}
}

//使用DocumentFragment劫持挂载的目标节点
function nodeToFragment(node,vm){
	var flag = document.createDocumentFragment();
	var child;
	while(child = node.firstChild){
		compile(child,vm);
		flag.append(child);
	}
	return flag;
}

function Vue(options){
	this.data = options.data;
	var data = this.data;

	observe(data,this);

	var id = options.el;
	var dom = nodeToFragment(document.getElementById(id),this);
	//编译完成后将dom返回到app中
	document.getElementById(id).appendChild(dom);
}

var vm = new Vue({
	el:'app',
	data:{
		text:'hello world'
	}
})
</script>
</body>
</html>

 

本文转载自:http://www.cnblogs.com/kidney/p/6052935.html?utm_source=gold_browser_extension

共有 人打赏支持
别人说我名字很长
粉丝 55
博文 255
码字总数 105359
作品 0
济南
程序员
私信 提问
深入理解Vue的watch实现原理及其实现方式

理解Vue中Watch的实现原理和方式之前,你需要深入的理解MVVM的实现原理,如果你还不是很理解,推荐你阅读我之前的几篇文章: 彻底搞懂Vue针对数组和双向绑定(MVVM)的处理方式 vue.js源码解读...

wangweianger
05/14
0
0
Vue和React数据绑定对比

在数据绑定上来说,vue的特色是双向数据绑定,而在react中是单向数据绑定。 一 单向和双向数据绑定其实不是完全没关系的 表单的双向绑定,说到底不过是 (value 的单向绑定 + onChange 事件侦...

pattyzzh
05/14
0
0
关于Vue和React区别的一些笔记

这篇文章记录我在使用Vue和React的时候,对他们的不同之处的一些思考,不仅局限于他们本身,也会包括比如 等经常搭配使用的工具。因为涉及到的内容很多,可能下面的每一个点都能写成一篇文章...

言川
07/30
0
0
西安电话面试:谈谈Vue数据双向绑定原理,看看你的回答能打几分

最近我参加了一次来自西安的电话面试(第二轮,技术面),是大厂还是小作坊我在这里按下不表,先来说说这次电面给我留下印象较深的几道面试题,这次先来谈谈Vue的数据双向绑定原理。 情景再现...

闰土大叔
04/25
0
0
个人理解Vue和React区别

监听数据变化的实现原理不同 Vue 通过 getter/setter 以及一些函数的劫持,能精确知道数据变化,不需要特别的优化就能达到很好的性能 React 默认是通过比较引用的方式进行的,如果不优化(P...

binbinsilk
09/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

myeclipse 启动到10分之一左右就挂了

删掉 {workspace}/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi

夜醒者
8分钟前
0
0
Hive on Spark 伪分布式环境搭建过程记录

进入hive cli是,会有如下提示: Hive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine (i.e. spark, tez) ......

PeakFang-BOK
15分钟前
0
0
用户输入和while 循环

# 用户输入和while循环# 7.1函数input() 的工作原理# 函数input() 让程序暂停运行,等待用户输入一些文本。获取用户输入后,Python将其存储在一个变量中,以方便你使用。message = inp...

吕湘颖
15分钟前
0
0
开发函数计算的正确姿势 —— 排查超时问题

写不尽的 code,查不完的 bug 通常我们写 bug,哦,不对,写代码时总不会一帆风顺,往往各种 bug 充斥其中,即使测试有较高的代码覆盖率往往也会有漏网之鱼。能写出一些比较隐蔽或者看起来像...

阿里云云栖社区
20分钟前
1
0
Python3新特性

一、类型注解 例子: def add(x:int, y:int) -> int: return x + y 解释: 类型`的形式指定函数的**参数类型**,用`-> 类型`的形式指定函数的**返回值类型 然后特别要强调的是,Pyt...

_Change_
35分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部