美文网首页
109、vue数据劫持

109、vue数据劫持

作者: world_7735 | 来源:发表于2019-11-21 15:48 被阅读0次

mvvm.js

function Jiechi(options = {}) {
    this.$options = options;//将所有属性挂载到options上
    var data = this._data = this.$options.data;
    observer(data);
    // 这里解决的是把所有data属性存放到实例上面可以让实例直接访问属性。现在是jiechi._data.a要转换成比如jiechi.a
    for (let key in data) {
        Object.defineProperty(this, key, {
            enumerable: true,
            get() {
                return this._data[key];
            }, set(newVal) {
                this._data[key] = newVal;
            }
        })
    }
    new Compile(options.el, this)
}
function Compile(el, vm) {
    //el 表示替换的范围
    vm.$el = document.querySelector(el);
    console.log(vm.$el);
    // 创建文档碎片把属性都放到里面
    let fragment = document.createDocumentFragment();//将html内容存到内存里
    while (child = vm.$el.firstChild) {
        fragment.appendChild(child);
    }
    console.log(fragment);
    replace(fragment)
    function replace(fragment) {
        Array.from(fragment.childNodes).forEach(function (node) {
            let text = node.textContent.replace(/^\s*|\s*$/g,"");
            let reg = /\{\{(.*)\}\}/;
            if (node.nodeType === 3 && reg.test(text)) {
                // console.log(RegExp.$1)
                let arr=RegExp.$1.split('.');
                let val=vm;
                arr.forEach(function(k){//取this.a.a
                    val=val[k];
                });
                node.textContent=text.replace(/\{\{(.*)\}\}/,val);
            }
            if (node.childNodes.length>0) {
                replace(node);
            }
        });
    }
    vm.$el.appendChild(fragment);
}
//vm.$options
//观察对象给对象增加ObjectDefineProperty
function Observe(data) {//这里写我们的主要逻辑
    for (let key in data) {//把data属性通过object
        let val = data[key];
        //默认遍历data中劫持所有属性------解决劫持对象多层问题保证所有对象都会被劫持
        observer(val);
        //.defineproperty的方式 定义属性
        Object.defineProperty(data, key, {
            enumerable: true,
            get() {
                return val;
            },
            set(newval) {
                if (newval == val) {//如果设置的值和以前的一样的时候直接返回
                    return;
                }
                val = newval;
                // 解决新加属性添加到劫持数据里
                observer(newval);
            }
        })
    }
}
function observer(data) {
    if (typeof data != 'object') return;
    return new Observe(data);
}



// 发布订阅
// 绑定的方法 都有update属性
function Dep(){
    this.subs=[];
}
Dep.prototype.addSub=function(sub){
    this.subs.push(sub);
}
Dep.prototype.notify=function(){
    this.subs.forEach(sub=>sub.update());
}
function Watcher(fn){
    this.fn=fn;
}
Watcher.prototype.update=function(){
    this.fn();
}




// 下面的数据劫持只是当前第一层数据比如:   a:1
//  如果a:{a:1}就不行了


// function Jiechi(options={}){
//     this.$options=options;//将所有属性挂载到options上
//     var data=this._data=this.$options.data;
//     observer(data);
// }
// //vm.$options
// //观察对象给对象增加ObjectDefineProperty
// function Observe(data){//这里写我们的主要逻辑
//     for(let key in data){//把data属性通过object
//         let val=data[key];
//         //
//         //.defineproperty的方式 定义属性
//         Object.defineProperty(data,key,{
//             enumerable:true,
//             get(){
//                 return val;
//             },
//             set(newval){
//                 if(newval==val){//如果设置的值和以前的一样的时候直接返回
//                     return;
//                 }
//                 val=newval
//             }
//         })
//     }
// }
// function observer(data){
//   return   new Observe(data);
// }

1.html

<html>

<head>
  <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>

<body>
  <div id="app">
    <p>{{a.a}}</p>
    <p>{{a.b}}</p>
  </div>
</body>

</html>
<script src="mvvm.js"></script>
<script>
  let jiechi=new Jiechi({
    el: '#app',
    data:{
     a:{a:'a',b:'b'}
    }
  })
console.log(jiechi);

</script>

相关文章

  • 109、vue数据劫持

    mvvm.js 1.html

  • 自己动手实现MVVM

    1、数据劫持(vue):通过Object.defineProperty()去劫持数据每个属性对应的getter和s...

  • VUE的双向绑定原理

    数据劫持(vue.js) 1.vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过对象的定义属...

  • vue 双向数据绑定原理

    vue双向数据绑定采用数据劫持结合系统-订阅者模式的方式,通过Object.defineProperty()来劫持...

  • vue数据绑定原理

    实现原理:vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的.1)数据劫持、vue是通过Obje...

  • Vue2.x 的双向绑定原理及实现

    Vue 数据双向绑定原理 Vue 是利用的 Object.defineProperty()方法进行的数据劫持,利用...

  • vue双向绑定原理(一)

    vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的,那么vue是如果进行数据劫持的,我们可以先来...

  • vue的双向绑定分享(一)

    vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的,那么vue是如果进行数据劫持的,我们可以先来...

  • vue实现双向绑定原理

    原理 vue数据双向绑定通过‘数据劫持’ + 订阅发布模式实现 数据劫持 指的是在访问或者修改对象的某个属性时,通...

  • Vue 核心之数据劫持

    Vue 核心之数据劫持 Angular、Regular、Vue、React等等可以实现数据绑定,再也不需要手动进行...

网友评论

      本文标题:109、vue数据劫持

      本文链接:https://www.haomeiwen.com/subject/stnnictx.html