zoukankan      html  css  js  c++  java
  • mvvm实现一个简单的vue

    vue,基于mvvm模式下的一个前端框架

      mvvm模式下简单的实现数据代理,数据劫持

      1.是用Object.defineProperty 实现数据代理

      2.使用发布订阅者模式,配合 Object.defineProperty,实现数据劫持

        数据劫持包括依赖收集和依赖促发

      (只考虑最简单的方式,并且没有包括具体的依赖收集,我模拟的依赖收集,依赖收集得是在模板解析的时候,需要使用正则匹配出vue的一般指令和表达式)

    /* 实现一个简易的vue */
    class myvue {
        constructor (option) {
            let _self = this
            this._data = option.data
            this.proxydata(_self)
            /* 使用发布订阅者模式实现数据劫持 */
            this.Datahijacking(_self)
    
            /* 实现一下模拟依赖收集 */
            /* 本身模板解析时,会使用正则去匹配表达式和一般指令
                匹配成功的表示是和一般指令都会调用以此数据劫持上的get方法
            */
            /* 假知我们传入的就是name 和 age */
            this._data.name;
            this._data.name;
            this._data.name;       
            this._data.age;
            this._data.age;
            /* 上面代表模板解析的时候一共调用的三次name 和 两次age */
        }
        /* 实现vue对_data数据的代理 */
        proxydata(_self) {
            /* 遍历传入的data的所有属性 */
            Object.keys(_self._data).forEach(key=>{
                Object.defineProperty(_self,key,{
                    configurable:true,
                    enumerable: true,
                    get () {
                        return _self._data[key]
                    },
                    set (val) {
                        _self._data[key] = val
                    }
                })
            })
        }
        /* 对_data数据劫持 */
        Datahijacking(_self) {
            Object.keys(_self._data).forEach(key=>{
                let value = _self._data[key]
                var dep = new Dep();
                Object.defineProperty(_self._data,key,{
                    configurable:true,
                    enumerable: true,
                    get () {
                        dep.addsubs(dep.id,new watch(key))
                        return value
                    },
                    set (val) {
                        dep.notify(val)
                    }
                })
            })
        }
    }
    
    var uid = 0;
    class Dep {
        constructor () {
            this.id = uid++;
            this.handlers = []
        }
        /* 依赖添加 */
        addsubs (id,fn) {
            if(!this.handlers[id]) {
                this.handlers[id] = []
            }
            this.handlers[id].push(fn)
        }
        /* 依赖促发 */
        notify (val) {
            if(this.handlers) {
                this.handlers[this.id].forEach(fn=>{                
                    fn.update(val);
                })
            }
        }
    }
    /* 具体订阅者 */
    class watch {
        constructor (name) {
            this.name = name
        }
        update (val) {
            /* 模拟试图更新 */
            console.log('视图更新了'+val)
        }
    }
    
    let vm = new myvue({data:{
        name: 'czklove',
        age: '17'
    }})
    console.log(vm)
    
    vm.name = 'czklovel11'
  • 相关阅读:
    Java第一次作业
    第十一次作业
    第十次作业
    第九次作业
    第五次作业
    第四次作业
    第三次作业
    第二次作业
    Java23种设计模式
    第三次作业
  • 原文地址:https://www.cnblogs.com/czkolve/p/10927391.html
Copyright © 2011-2022 走看看