最近研究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);
}

支持IE6、IE7、IE8等低端浏览器的简化版vue的更多相关文章

  1. JS代码判断浏览器版本,支持IE6,IE7,IE8,IE9!三种方法!

    web开发的时候有时候会用到JS检测IE的版本,下面是检测Microsoft Internet Explorer版本的三种代码! 方法一: <script type="text/jav ...

  2. JS代码判断IE6,IE7,IE8,IE9的函数代码

    JS代码判断浏览器版本,支持IE6,IE7,IE8,IE9!做网页有时候会用到JS检测IE的版本,下面是检测Microsoft Internet Explorer版本的三种代码 做网页有时候会用到JS ...

  3. 让IE6/IE7/IE8浏览器支持CSS3属性

    让IE6/IE7/IE8浏览器支持CSS3属性 一.下载 您可以狠狠地点击这里:ie-css3.htc,这个玩意儿是让IE浏览器支持CSS3表现的关键东东. 二.上面的是什么东西 首先说说.htc文件 ...

  4. 如何让低版本的IE浏览器(IE6/IE7/IE8)支持HTML5 header等新标签

    html5提供的一些新标签(article,aside,dialog,footer,header,section,footer,nav,figure,menu)使用起来非常的方便,但是低版本的IE浏览 ...

  5. 解决IE6/IE7/IE8不支持before,after问题

    对从事web开发的朋友来讲,低版本的IE永远是一个痛点,不支持最新技术(如css3,html5). 在现在web开发中使用图标字体已经很广泛,如Font Awesome,Bootstrap等,字体图片 ...

  6. IE6 IE7 IE8(Q) 不支持 JSON 对象

    标准参考 JSON 是一种数据交换格式,RFC 4627 对 JSON 进行了详细描述. 根据 ECMA-262(ECMAScript)第 5 版中描述,JSON 是一个包含了函数 parse 和 s ...

  7. IE6 IE7 IE8 的函数声明和函数表达式的实现与其他浏览器有差异

    标准参考 函数声明和函数表达式 定义一个函数有两种途径:函数声明和函数表达式. 函数声明: function Identifier ( FormalParameterList opt ) { Func ...

  8. 让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法--(转)

    如有雷同,不胜荣幸,若转载,请注明 让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法 最近做一个Web网站,之前一直觉得bootstrap非常好,这次使用了boot ...

  9. 针对IE6,IE7,IE8,IE9,FF等不同浏览器的CSS写法

    首先我们介绍一下HACK原理,就是不同浏览器对字符的识别不同 在 CSS中常用特殊字符识别表: (1)*: IE6+IE7都能识别*,而标准浏览器FF+IE8是不能识别*的; (2)!importan ...

随机推荐

  1. 吴裕雄--天生自然python Google深度学习框架:深度学习与深层神经网络

  2. 吴裕雄--天生自然python机器学习:机器学习简介

    除却一些无关紧要的情况,人们很难直接从原始数据本身获得所需信息.例如 ,对于垃圾邮 件的检测,侦测一个单词是否存在并没有太大的作用,然而当某几个特定单词同时出现时,再辅 以考察邮件长度及其他因素,人们 ...

  3. LeetCode No.115,116,117

    No.115 NumDistinct 不同的子序列 题目 给定一个字符串 S 和一个字符串 T,计算在 S 的子序列中 T 出现的个数. 一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且 ...

  4. xpath-helper 插件下载

    链接:https://pan.baidu.com/s/1YuTGrdwwAKQd2sIcuarBHQ 提取码:qb8p

  5. 位移&二进制转换&原码&反码&补码

    << 左移 按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零. 格式 需要移位的数字 << 移位的次数 计算过程 1. 按二进制形式把所有的数字向左 ...

  6. manacher算法 详解+模板

    manacher算法可以解决字符串的回文子串长度问题. 个人感觉szy学长讲的非常好,讲过之后基本上就理解了. 那就讲一下个人的理解.(参考了szy学长的ppt) 如果一个回文子串的长度是偶数,对称轴 ...

  7. 企业级rancher搭建Kubernetes(采用rancher管理平台搭建k8s)

    一.简介 Rancher简介 来源官方:https://www.cnrancher.com/ Rancher是一个开源的企业级容器管理平台.通过Rancher,企业再也不必自己使用一系列的开源软件去从 ...

  8. Django ORM必会13条之外的查询方法

    基于双下划线的查询 # 价格 大于 小于 大于等于 小于等于 filter(price__gt=') # 筛选出大于90 filter(price__lt=') # 筛选出小于90 filter(pr ...

  9. kNN算法 Demo

    项目链接: https://github.com/WES6/kNN

  10. hexo创建新文章的正确方法

    起因 之前我一直是通过复制以前的文章的形式来创建一个新的文档,但是这一次似乎遇到了一些问题.我将文章写完之后,准备进行预览,输入hexo s命令.在预览页面却没有显示出新的文章,还是和之前的页面是一样 ...