支持IE6、IE7、IE8等低端浏览器的简化版vue
程序员文章站
2022-07-09 19:59:22
最近研究Vue的底层原理,写了一个简化版的Vue,可以在支持IE6、IE7、IE8等低端浏览器运行。由于低端浏览器不支持对象属性定义,所以设置属性不支持直接赋值,需要调用虚拟机实例的set方法。目前只实现了基础的方法,后续继续完善! ......
最近研究vue的底层原理,写了一个简化版的vue,可以在支持ie6、ie7、ie8等低端浏览器运行。由于低端浏览器不支持对象属性定义,所以设置属性不支持直接赋值,需要调用虚拟机实例的set方法。目前只实现了基础的方法,后续继续完善!
index.html
<!doctype html> <html> <head> <title>简化版vue</title> <script> window.onerror=function(){ return true; } </script> </head> <body> <hr /> <div id="simplevue"> <button v-on:click="copy">戳我</button> <div> <textarea v-model="name"></textarea> <div v-text="name"></div> </div> <div> <select v-model="name"> <option value="name1" selected>name1</option> <option value="name2">name2</option> <option value="name3">name3</option> </select> </div> <hr> <button v-on:click="show">显示/隐藏</button> <div v-if="isshow"> <input type="text" style="width: 300px" v-model="website"> <div v-text="website"></div> </div> </div> <script src="vmm.js"></script> <script> var vm = new vmm({ el: '#simplevue', data: { name: '测试', website: 'https://github.com/steezer', isshow: true }, methods: { copy: function(){ vm.set('name', this.name +'测试'); }, show: function(){ vm.set('isshow', !this.isshow); } } }); </script> </body> </html>
vmm.js
function vmm(options){ /** * 订阅器构造 用来接收属性值的相关数据的变化通知 从而更新视图 * * @param {object} vm 虚拟机对象 * @param {htmlelement} el node节点 * @param {string} attr 属性名称 * @param {object} val 属性值 */ function watcher(vm, el, attr, val){ this.vm = vm; this.el = el; this.attr = attr; this.val = val; /** * 将收到的新的数据更新在视图中 */ this.update = function() { if (this.vm.$data[this.val] === true) { this.el.style.display = 'block'; } else if (this.vm.$data[this.val] === false) { this.el.style.display = 'none'; } else { this.el[this.attr] = this.vm.$data[this.val]; } } // 初始化订阅器时更新一下视图 this.update(); } /** * 获取对象 * * @param {object|string} id * @returns object */ function getelem(id){ if(typeof(id)=='object'){ return id; } var target=id+'', prefix=target.substr(0,1), target=target.substr(1); if(prefix=='#'){ return document.getelementbyid(target); } if(prefix=='.'){ return document.getelementsbyclassname(target); } return document.getelementsbytagname(target); } function getattr(elem, name) { var node = elem.getattributenode(name); if (node && node.specified) { return node.nodevalue; } else { return undefined; } } function addevent(node, type, handle){ if(document.addeventlistener){ node.addeventlistener(type, handle, false); }else{ node.attachevent('on'+type, function(){ handle.call(node, arguments); }); }; } this.$el = getelem(options.el); this.$data = options.data; this.$methods = options.methods; this.owatcherobj = {}; // 获取属性 this.get=function(key){ return this.$data[key]; } // 设置属性 this.set=function(key, newval){ var value=this.$data[key]; if (newval !== value) { this.$data[key] = newval; if(typeof(this.owatcherobj[key])!="undefined"){ var watchers=this.owatcherobj[key]; for(var i=0; i< watchers.length; i++){ watchers[i].update(); } } } } /** * 节点dom解析器 */ this.compile=function(el) { var nodes = el.children, $this=this, addwatcher=function(node, attr, val){ if(typeof($this.owatcherobj[val])=='undefined'){ $this.owatcherobj[val]=[]; } $this.owatcherobj[val].push(new watcher($this, node, attr, val)); }; // 迭代同级所有节点 var values=[]; for(var k in el){ values.push(k) } for (var i = 0; i < nodes.length; i++) { var node = nodes[i],val; if (node.children.length > 0) { this.compile(node); // 递归所有子节点 } // 点击事件 val=getattr(node, 'v-on:click'); if (val) { if(typeof($this.$methods[val])=="function"){ addevent(node, 'click', (function(val){ return function(e){ $this.$methods[val].call($this.$data, e); } })(val)); } } // if指令 val=getattr(node, 'v-if'); if (val) { addwatcher(node, "", val); } // model val=getattr(node, 'v-model'); if (val) { var event=node.tagname.match(/select/i) ? 'change' : ('oninput' in node ? 'input' : 'propertychange'); addwatcher(node, "value", val); addevent(node, event, (function(i, val){ return function(e){ $this.set(val, nodes[i].value); } })(i, val)); } // text val=getattr(node, 'v-text'); if (val) { addwatcher(node, "innertext", val); } // html val=getattr(node, 'v-html'); if (val) { addwatcher(node, "innerhtml", val); } } } // 节点解析 this.compile(this.$el); }
上一篇: Spring boot 加入拦截器
下一篇: Django之初学习