简化版vue代码 支持IE6、IE7、IE8低端浏览器

    2020-03-09 15:01:59

    发表时间:

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

    作者:程序人生
    来源:博客园

    KEYAN编码网址解码

    · END ·

    关键词:简化版vue,支持IE6、IE7、IE8 标签:支持IE6、IE7、IE8等低端浏览器的简化版vue

    以上内容来源本站

文章推荐:

最新 工具

简化版vue代码 支持IE6、IE7、IE8低端浏览器

发表时间:2020-03-09 15:01:59

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

作者:程序人生
来源:博客园

· END ·

关键词: 标签:

以上内容来源本站

//评论数 //参与数

博主简介 - 广告合作 - 文章投稿 - 故事文摘 - 典范条目 - 博主新闻

 百科创建更新

网站地图

 

© 2020 blog.dgso.cn 赵彦彬博客 吉ICP备17000796号-1