zoukankan      html  css  js  c++  java
  • Vue中的数据劫持

      大家好,今天我给大家讲解一下Vue中的数据劫持是如何实现的

      1.在这之前呢,不知道大家知不知道 Object.defineProperty 这个属性呢,如果知道的话,请忽略这一段。

      1. 语法:Object.defineProperty(obj, prop, descriptor) 
      2. 参数:
        1. obj: 要在其上定义属性的对象。
        2. prop: 要定义或修改的属性的名称或名称
        3. descriptor: 定义或修改的属性的描述符。
      3. 返回值:传递给函数的对象。(返回值这个一般不怎么用)

        而在这个 descriptor 有很多的属性,还有 get 和 set 的方法,这里就介绍了 get 和 set 这两个方法,其它的可以去官网了解一下。  

        get: 用作属性的吸气剂或undefined没有吸气剂的函数当访问该属性时,将调用该函数而无需使用参数,并且将其this设置为访问该属性所通过的对象(由于继承,它可能不是在其上定义该属性的对象)。返回值将用作属性的值。
    默认为undefined

        set: 用作属性的setter的函数,或者undefined如果没有setter 的函数。将属性分配给该函数时,将使用一个参数(将值分配给该属性)并将this该对象设置为分配该属性的对象来调用此函数。
    默认为undefined

           这个就是官网的介绍啦,就我的个人理解

      1. get 就是返回这个属性的值,也就是说,每次获取这个属性的值时,返回的都是我们这里定义的返回值
      2. set 就是当这个属性的值重新赋值的时候要做的事情,可以自己定义,可以是返回新值,也可以是返回你自己定义的值

           

          废话不多说,我们来试验一下。

           let obj = {
                    name: '小明',
                    age: 21
                }
                function fun(obj,name){
                    let value = obj[name]
                    Object.defineProperty(obj,'name',{
                        //get 方法就是每次获取这个属性的值时,执行的方法
                        get(){
                            console.log('我是 get 中的')
                            return  '我是 get 获取的' + value
                        },
                        //set 方法就是每次设置这个属性的值时,执行的方法
                        set(newVal){ //newVal是给当前的值从新赋值的值,也就是新值
                            console.log('我是 set 中的')
                            value = ',我是 set 设置的' + newVal
                        }
                    })
                }
                fun(obj,'name')
                console.log(obj.name) //打印两次 1、我是 get 中的  2、我是 get 获取的小明
                obj.name = '小红' //打印一次 1、我是 set 中的
                console.log(obj.name) //打印两次 1、我是 get 中的  2、我是 get 获取的,我是 set 设置的小红

           

       2、Vue 中的数据劫持也就使用了这样的方法,让我们看看 Vue 中是如何实现的吧!

      

    /**
     * 数据劫持
     */
    class Observer{
        constructor(data) {
            this.observer(data);
        }
        observer(data){
            //如果是对象才观察
            if(data && typeof data === 'object'){
                
                for (let key in data) { //循环 data 中的所有子项
                    this.defineReactive(data,key,data[key]);
                }
            }
        }
        //实现数据劫持
        defineReactive(obj,key,value){
            this.observer(value); //如果传进来的参数是对象,就回调一下这个函数,就是一个递归函数
            
            let dep = new Dep(); //给每一个属性都添加一个具有发布和订阅的功能
            
            Object.defineProperty(obj,key,{
                get(){
                    //创建watcher时,会获取到对应的内容 并且把watcher放到了全局上
                    Dep.target && dep.addSub(Dep.target);
                    return value;
                },
                set: (newVal)=>{
                    if(value !== newVal){
                        this.observer(newVal); //给设置的新值也加上 get set 方法
                        value = newVal;
                        dep.notify(); //执行观察者更新时的函数
                    }
                    
                }
            })
        }
    }

       

      上面就是Vue中实现数据劫持的过程,当然,数据劫持中的 watcher 观察者, Dep 发布和订阅这里就不介绍了,下一篇在为您介绍。

  • 相关阅读:
    cholesky分解
    LU分解(2)
    LU分解(1)
    自定义UITableView的Seperator
    iOS屏蔽高频点击技巧
    iOS动态管理AutoLayout的约束NSLayoutConstraint
    Reachability几个常用方法
    XCode4 下制作Framework的方法
    StoryBoard 的使用
    Objective-C RunTime
  • 原文地址:https://www.cnblogs.com/nie5135257/p/12110988.html
Copyright © 2011-2022 走看看