当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 支持IE6、IE7、IE8等低端浏览器的简化版vue

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

2020年03月09日  | 移动技术网IT编程  | 我要评论

最近研究vue的底层原理,写了一个简化版的vue,可以在支持ie6、ie7、ie8等低端浏览器运行。由于低端浏览器不支持对象属性定义,所以设置属性不支持直接赋值,需要调用虚拟机实例的set方法。目前只实现了基础的方法,后续继续完善!

<!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);
}

 

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网