vue.js双向数据绑定实现原理
2017-10-01 11:44
1471 查看
源码如下:
参考:http://www.jb51.net/article/99129.htm
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <input type="text" v-model="text"> {{text}} </div> <script> /*var dom = nodeToFragment(document.getElementById('app')); console.log(dom);*/ 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;//获取v-model绑定的属性名 //放在该位置原因是获取name值 node.addEventListener('input',function (e) { //给相应的data属性赋值,进而触发该属性的set方法 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;//1.获取匹配到的字符串 name = name.trim(); //node.nodeValue = vm[name];//将data的值赋值给该node new Watcher(vm,node,name); } } } function nodeToFragment(node,vm) { var flag = document.createDocumentFragment(); var child; while(child = node.firstChild){ compile(child,vm); flag.append(child); } return flag; } function defineReactive(obj,key,val) { var dep = new Dep(); Object.defineProperty(obj,key,{ get:function () { if(Dep.target) dep.addSub(Dep.target); return val; }, set:function (newVal) { if(newVal===val) return ; val = newVal; //console.log(val); //作为发布者发出通知 dep.notify(); } }); } function observe(obj,vm) { Object.keys(obj).forEach(function (key) { defineReactive(vm,key,obj[key]); }) } 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('app').appendChild(dom); } 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 } }; var vm = new Vue({ el:'app', data:{ text:'hello world' } }); </script> </body> </html>
参考:http://www.jb51.net/article/99129.htm
相关文章推荐
- vue.js双向数据绑定原理解析及模拟demo的实现
- Vue.js双向绑定的实现原理
- Vue.js实现双向数据绑定(表单自动赋值、表单自动取值)
- 深入理解vue.js双向绑定的实现原理
- vue中数据双向绑定的实现原理
- 浅谈vue中数据双向绑定的实现原理
- Vue实现双向绑定的原理以及响应式数据的方法
- Vue.js双向绑定的实现原理
- 深入理解vue.js双向绑定的实现原理
- Vue实现双向绑定的原理以及响应式数据
- Vue数据双向绑定原理及简单实现方法
- vue.js--基础 事件结合双向数据绑定实现todolist,增加和删除功能
- Vue.js双向绑定的实现原理
- Vue.js双向绑定实现原理详解
- 【学习笔记】Vue中实现双向数据绑定的原理
- Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定)
- vue双向数据绑定的实现原理
- Vue.js双向绑定的实现原理
- Vue.js双向数据绑定实现
- Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定)