function miniVue(options) { this.$el = document.querySelector(options.el); this.$data = options.data; this.$methods = options.methods; this.bindings = {};
this.observer(this.$data); this.compile(this.$el); }
miniVue.prototype = { constructor:miniVue, observer:function(data) { for (var key in data) { this.bindings[key] = [];
var arr = this.bindings[key];
this.defineReactive(data,key,data[key],arr) } }, defineReactive:function(data,key,value,arr){ Object.defineProperty(data, key, { get() { return value; }, set(newVal) { if (newVal !== value) { value = newVal; arr.forEach((item)=> { item.updateView(); }) } } }) }, compile:function(el) { var nodes = ([]).slice.call(el.children); for (var i = 0; i < nodes.length; i++) { var node = nodes[i]; if (node.nodeType === 1 && !!node.childElementCount) { this.compile(node) }
if (node.nodeType === 1 && !node.childElementCount && node.textContent.trim()) { var v = this.textToExp(node.textContent); this.recordRelativeDom(node,"innerText",v,this) }
if (node.hasAttribute("v-model")) { var attrVal = node.getAttribute("v-model"); node.addEventListener("input", ((i) => { this.recordRelativeDom(node,"value",attrVal,this) return () => { this.$data[attrVal] = nodes[i].value; } })(i))
} if (node.hasAttribute("v-html")) { var attrVal = node.getAttribute("v-html"); this.recordRelativeDom(node,"innerHTML",attrVal,this) } if (node.hasAttribute("v-text")) { var attrVal = node.getAttribute("v-text"); this.recordRelativeDom(node,"innerText",attrVal,this) } if (node.hasAttribute("v-on:click")) { var attrVal = node.getAttribute("v-on:click"); node.addEventListener("click", this.$methods[attrVal].bind(this.$data)); } } }, recordRelativeDom:function(node,attr,attrVal,vm){ var curData = this.bindings[attrVal] if(curData){ curData.push(new Notify(node, attr, attrVal, vm)); }else{ console.log('变量'+attrVal+'没有被注册!'); } }, textToExp:function(text){ var tar, pieces = text.trim().split(/({{.+?}})/g); pieces = pieces.map(piece => { if (!!piece) { tar = piece.replace(/^{{|}}$/g, ''); } }); return tar.trim(); } }
function Notify(el, attr, val, vm) { this.el = el; this.attr = attr; this.val = val; this.vm = vm; this.updateView(); }
Notify.prototype = { constructor:Notify, updateView:function() { this.el[this.attr] = this.vm.$data[this.val]; } }
|
访客评论