仿vue实现

##看了 OBKoro1大神的文章,受益匪浅.照着他的代码敲了几遍 一点一点的理解 才搞清楚 对于vue,有了更深的理解.谢谢 文章链接 juejin.im/post/5b2df5…

function myVue(options = {}){//默认空对象 防止不穿
    this.$options = options;
    this.$el = document.querySelector(options.el);
    this._data = this.$options.data; 
    this._watcherTpl = {};//数据的观测池
    this._observer(this.$options.data);
    this.complie(this.$el)
}
muVue.prototype._observer = function(obj){
    var _this = this;
    Object.keys(obj).forEach( key =>{
        _this._watcherTpl[key] ={
            _directives:[]
        }
        let value = obj[key];
        Object.defineProperty(this._data,key,{
            configurable:true,//可以被删除
            enumerable:true,//可以被枚举
            get(){
                return value
            },
            set(newVal){
                if(value != newVal ){
                    value = newVal;
                    this._watcherTpl[key].directives.forEach(item=>{
                        item.update()
                    })
                }
            }
        })
    })
}
myVue.prototype._complie = function(el){
    var _this = this,nodes = el.children;
    for (var i=0,len = nodes.length;i<len;i++){
        var node = nodes[i];
        if(node.length){
            _this._compile(node)
        }
        if(node.hasAttrubute('v-model')&&(node.tagName == 'INPUT'||node.tagName == 'TEXTERA')){
          node.addEventListener('input',(function(){
               var attVal = node.getAttribute('v-model'); // 获取v-model绑定的值
                    _this._watcherTpl[attVal]._directives.push(new Watcher( // 将dom替换成属性的数据并发布订阅 在set的时候更新数据
                        node,
                        _this,
                        attVal,
                        'value'
                    ));
                    return function () {
                        _this._data[attVal] = nodes[key].value;  // input值改变的时候 将新值赋给数据 触发set=>set触发watch 更新视图
                    }
          })(i))  
        }
        if (node.hasAttribute('v-bind')) { // v-bind指令 
            var attrVal = node.getAttribute('v-bind'); // 绑定的data
            _this._watcherTpl[attrVal]._directives.push(new Watcher( // 将dom替换成属性的数据并发布订阅 在set的时候更新数据
                node,
                _this,
                attrVal,
                'innerHTML'
            ))
        }        
    }
}
function Watcher(vm,el,attVal,val){
    this.vm = vm;
    this.el = el;
    this.attVal = attVal;
    this.val = val;
    this.update()
}
Watcher.property.update = function(){
    return this.el(this.val) = this.vm._data[this.attVal]
}
复制代码

转载于:https://juejin.im/post/5c0a365be51d4570cf60d216

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值