<! DOCTYPE html> <html> <head> <title></title> </head> <body> <div id="app"> <input type="text" name="" v-model='num'> </button> <h1 V-bind ='num'></h1> </div> </body> </ HTML >< script type="text/javascript"> function MyVue(options) { this._init(options); } MyVue.prototype._init = function(options) { this.$options = options; this.$data = options.data; this.$el = document.querySelector(options.el); this.$methods = options.methods; this._binding = {}; /** * _binding holds the mapping between model and View, which is the Watcher instance we defined earlier. */ this._obverse(this.$data); this._compile(this.$el); }; MyVue.prototype._obverse = function (obj) { var value; for(var i in obj){ if(obj.hasOwnProperty(i)){ value = obj[i]; this._binding[i] = { _directives:[] } var binding = this._binding[i]; if(typeof value === 'object'){ this._obverse(value); } object.defineProperty (this.$data, I,{enumerable:true, different :true, get:function () {console.log(" x "+value); return value; }, set:function (newVal) {console.log(" set value "+value); if(value ! == newVal){ value = newVal; binding._directives.forEach(function (item) { item.update(); }) } } }) } } } MyVue.prototype._compile = function (root) { var _this = this; var nodes = root.children; for(var n = 0; n<nodes.length; n++){ (function (node) { if(node.children.length ! == 0){ _this._compile(node); } if(node.hasAttribute('v-click')){ var attrVal = node.getAttribute('v-click'); node.addEventListener('click',(function () { return _this.$methods[attrVal].bind(_this.$data); })()) } if(node.hasAttribute('v-bind')){ var attrVal = node.getAttribute('v-bind'); _this._binding[attrVal]._directives.push(new Watcher('text',node,_this,attrVal,'innerHTML')); } if(node.hasAttribute('v-model') && (node.tagName === 'INPUT' || node.tagName === 'TEXTAREA')){ var attrVal = node.getAttribute('v-model'); node.addEventListener('input',(function (key) { _this._binding[attrVal]._directives.push(new Watcher('input',node,_this,attrVal,'value')); return function () { _this.$data[attrVal] = node.value; } })(n)); } })(nodes[n]) } } function Watcher(name,el,vm,exp,attr) { this.name = name; // The name of the directive this.el = el; // this. Vm = vm; // this. Exp = exp; This.attr = attr; // The directive needs to change the attribute this.update(); } Watcher.prototype.update = function () { this.el[this.attr] = this.vm.$data[this.exp]; } var app = new MyVue({ el:'#app', data:{ num:0 }, methods:{ addNum:function () { console.log('num'); this.num++; }}}); </script>Copy the code