08数据代理

数据代理

数据代理:通过一个对象对另一个对象中属性的操作(读写)
作用:通过Object.defineProperty方法为桥梁,外部的一个对象对内部对象中属性及属性粒度的操作。(达到即用即读,即修即改)

由Object.defineProperty()方法实现。

  1. 知道传递几个参数
  2. 每个参数是什么类型
  3. 这个方法可以干什么

Vue底层的数据劫持、数据代理、计算属性等都用到此方法。

Object.defineProperty(obj,param,config)

通过Object.defineProerty()方法,传入的object对象,property属性,它是 现用现取,靠的是get(),改则set().

Object.defineProperty(object,property,config)
	- 传递三个参数:
		- 第一个:要给那个对象添加属性
		- 第二个:添加属性名称
		- 第三个:配置项:{
			value:18,
			enumerable:true,	 //控制属性是否可以枚举,默认值是false
            writable:true,		 //控制属性是否可以被修改,默认值是false
            configurable:true	 //控制属性是否可以被删除,默认值是false
            
            //当有人读取person的age属性时,get函数就会被调用,且返回值就是age的值
            get(){
				return 'hello'
            },
            //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
    		set(value){
                number = value
            }
        }


实例

<script>
    // 外部对象(属性)
    number = 18;

    // 原对象
    obj = {
        name:'alex',
        gender:'男',
        // age:number           // 在原对象中添加属性,虽然可以,但是粒度却不足(属性的详细: 是否可修改,是否可枚举,是否可以被删除。。。)
    }

    // 使用数据代理,添加对象属性
    Object.defineProperty(obj,'age',{
        // value:18,           // 使用数据代理,可以对属性粒度操控,value默认不可修改。
        // writable:true,      // 对属性的粒度控制,是否可以修改。默认为false。
        // enumerable:true,    // 对属性的粒度控制,是否可以被枚举。默认为false。
        // configurable:true,  // 对属性的粒度控制,是否可以被删除,默认是false。

        // 当有人访问此对象age属性时,就会掉用age的get()方法(getter),返回的数据就是age的值。
        get(){
            return number
        },
        // 当有人修改此对象age属性时,就会掉用age的set()方法(setter),收到的数据就是age的值。 
        set(value){
            console.log(true);
            number=value
        },

    })

    //  数据代理
    	// “内部属性需要动态操作,且不需要重复的人为修改内部数据时。”  --- 数据代理
    	// 当我们需要修改内部的数据时,同时又不想人力的执行重复的操作。我们可以通过数据代理来实现,外部修改全局修改的效果,
    	/*
                number  (外部力)
                ↑↓
                关联   ←←  Object.defineProperty  (桥梁,纽带)
                ↑↓
                obj     (内部属性)
         */
</script>

简单的数据代理

<script type="text/javascript" >
    let obj = {x:100}
	let obj2= {y:200}
	Object.defineProperty (obj2,"x",{
            get(){
  		return obj.x
            },
  	    set(value){
          	obj.x = value
      	    }
	}
</script>

vue中使用数据代理

主要弄明白getter线和setter线即可。

总结


    1.Vue中的数据代理;
        通过vm对象来代理data对象中属性的操作(读/写)
    2.Vue中数据代理的好处:
        更加方便的操作data中的数据
    3.基本原理:
        通过object.defineProperty()把data对象中所有属性添加到vm上.为每一个添加到vm上的属性,都指定一个getter/setter。
        在getter/setter内部去操作(读/写)data中对应的属性。





   vm._data === data (vm._data本身的数据就是从options中直接获取) ===> vm._data === options.data === data
   data.name='alex'  ==> vm._data.name='alex' ==> vm.name='alex' (页面的name=‘alex’)  

                                            options:data.name
                                                    ↓↑
        数据代理    ←Object.defineProperty()-→   vm:_data.name  --→ 数据劫持
                                                    ↓↑ 
            ↑↓      ←Object.defineProperty()-→      vm.name  (通过getter去vm._data中读取,通过setter映射到vm._data中修改)


    数据代理是:
        - vm中vm._data.xxoo中数据与vm.xxoo的代理
        - 将vm._data中的数据放到vm中,目的是为了让编码更便捷。
        - 通过Object.defineProperty()实现
	

图例

image-20220811204702524

image-20220811201749277

实例

<div id="root">
    <h3>name: {{name}}</h3>
    <h3>address: {{address}}</h3>
</div>
<script>
    Vue.config.productionTip=false;

    let data = {
            name:'redskaber',
            address:'hunan'
        }
    
    const vm = new Vue({
        el:'#root',
        data
    })  

</script>
posted @ 2022-09-06 15:52  Redskaber  阅读(31)  评论(0)    收藏  举报