支持IE6、IE7、IE8等低端浏览器的简化版vue

vue

最近研究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 的全部内容, 来源链接: utcz.com/z/375696.html

回到顶部