最近研究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. ACM-ICPC Nanjing Onsite 2018 I. Magic Potion

    题意:类似二分图匹配给的题目,不过这次在这里给出了k,表示没人可以再多一次匹配机会,这次匹配不能用上一次被匹配的对象 分析:不能用匈牙利做俩次匹配,因为俩次的最大匹配并不等价于总和的匹配,事实证明,你 ...

  2. python学习笔记(16)hashlib.md5摘要算法(哈希算法)

    一.摘要算法格式 import hashlib #导入hashlib模块 md = hashlib.md5() #获取一个md5加密算法对象 md.update('how to use md5 in ...

  3. C#阶段小结

    一.数据类型: (一)内建类型: 整型(int ,short, long ,byte ,uint ,ushort, ulong ,sbyte): 浮点型(double float decimal): ...

  4. 牛客-小w的a=b问题

    题目传送门 sol1:老实做,预处理出所有2到1e5的素数,对所有数进行分解质因数,然后对比因子个数.感觉有点卡常,用了快读然后多次优化之后才过的,map也用上了. 素数筛,快速分解质因数 #incl ...

  5. hadoop-2.5.2 源码学习1

  6. numpy中的ndarray与pandas中的series、dataframe的转换

    一个ndarray是一个多维同类数据容器.每一个数组有一个dtype属性,用来描述数组的数据类型. Series是一种一维数组型对象,包含了一个值序列,并且包含了数据标签----索引(index). ...

  7. 18)添加引号转移函数,防止SQL注入

    目录机构: 然后我的改动代码: MysqlDB.class.php <?php /** * Created by PhpStorm. * User: Interact * Date: 2017/ ...

  8. spring学习笔记四:AOP

    AOP(Aspect Orient Programming),面向切面编程,是对面向对象编程OOP的一种补充 面向对象编程使用静态角度考虑程序的结构,而面向切面编程是从动态角度考虑程序运行过程 AOP ...

  9. inventor卸载/完美解决安装失败/如何彻底卸载清除干净inventor各种残留注册表和文件的方法

    在卸载inventor重装inventor时发现安装失败,提示是已安装inventor或安装失败.这是因为上一次卸载inventor没有清理干净,系统会误认为已经安装inventor了.有的同学是新装 ...

  10. apache启动但是无法访问网页

    apache启动但是访问不了的问题排除??? 端口没有被占用,则需要考虑防火墙问题. 首先我们需要确保远程的Linux系统已经安装好,我们使用xshell远程SSH登录到Linux系统里,同时我们也要 ...