Vue03_vue属性_数据代理

Vue中

$ 开始的属性是供程序员开发使用的

_ 开始的属性是vue 框架底层使用的

Vue03_vue属性_数据代理_第1张图片

可以直接访问data 中的属性

使用数据代理机制实现

Vue03_vue属性_数据代理_第2张图片

 Vue03_vue属性_数据代理_第3张图片

数据代理机制: 通过访问代理对象的属性 间接 访问 目标对象的属性

数据代理机制 核心 Object.defineProperty 为对象添加一个属性

Object.defineProperty(obj, prop, descriptor)
obj 要定义属性的对象
prop 要定义或修改的属性的名称
descriptor 要定义或修改的属性描述符
返回值 被传递给函数的对象




    
    Title
    
    


    

Vue03_vue属性_数据代理_第4张图片

 book.name 赋值 无效 

Vue03_vue属性_数据代理_第5张图片

writable: true属性可修改,false属性不可修改



    
    Title
    
    


    

Vue03_vue属性_数据代理_第6张图片

getter setter 方法




    
    Title
    
    


    

有get set 配置项时,value writable 配置项不允许使用

Vue03_vue属性_数据代理_第7张图片

获取 添加 属性的 值

getter 方法被调用

Vue03_vue属性_数据代理_第8张图片

修改 添加 属性的 值

setter 方法被调用

Vue03_vue属性_数据代理_第9张图片

getter 方法必须有返回值,获取属性值时获取到的就是getter方法的返回值



    
    Title
    
    


    

Vue03_vue属性_数据代理_第10张图片

setter方法 参数 接收为属性赋的值



    
    Title
    
    


    

Vue03_vue属性_数据代理_第11张图片

book.name 获取属性值时,其实获取的是变量 tmp 的值

book.name="value" 给属性赋值时,其实是为变量tmp赋值

book.name 就代理了 变量 tmp




    
    Title
    
    


    

第一次获取tmp的值,undefined

book.name获取的其实是tmp 的值(调用getter方法),一样为 undefined

book.name="局外人",调用setter方法,为tmp赋值,

再次获取book.name 和 tmp 的值, 为   局外人

Vue03_vue属性_数据代理_第12张图片

数据代理机制的实现:




    
    Title
    
    


vue 数据代理对属性名的要求

不能以 $ or _ 开始




    
    Title
    
    


vm 对象中只有msg属性,没有_msg,$msg 属性,以$ or _ 开始的属性名 vue 不会做数据代理               $ _ 开始的属性名 是 vue框架 自己要用

Vue03_vue属性_数据代理_第13张图片

模拟 vue 数据代理

//定义一个类
class Vue {
    //定义构造函数
    constructor(option){
        //获取所有的属性名
        let propertys = Object.keys(option.data);
        //添加代理属性
        propertys.forEach(
            /* ()=> {} 形式为箭头函数 其内没有this ,会从上一级作用域寻找 this 变量
             function(){} 中的this 为调用该方法的对象,此处箭头函数中的this 从上一级作用域找到的 this 是 constructor 创建的对象
               */
             (propertyName,index) => {
                Object.defineProperty(this,propertyName,{
                    get(){
                        return option.data[propertyName];
                    },
                    set(val){
                        option.data[propertyName] = val;
                    }
                });
            }
        );

    }
}



    
    Title
    
    


Vue03_vue属性_数据代理_第14张图片

加上属性名限制

//定义一个类
class Vue {
    //定义构造函数
    constructor(option){
        //获取所有的属性名
        let propertys = Object.keys(option.data);
        //添加代理属性
        propertys.forEach(
            /* ()=> {} 形式为箭头函数 其内没有this ,会从上一级作用域寻找 this 变量
             function(){} 中的this 为调用该方法的对象,此处箭头函数中的this 从上一级作用域找到的 this 是 constructor 创建的对象
               */
             (propertyName,index) => {
                 //不以$ _ 开始的属性名 做数据代理
                 let firstChar = propertyName.charAt(0);
                 if( firstChar != '_' && firstChar !='$' ){
                     Object.defineProperty(this,propertyName, {
                         get() {
                             return option.data[propertyName];
                         },
                         set(val) {
                             option.data[propertyName] = val;
                         }
                     });
                 }
            }
        );

    }
}



    
    Title
    
    


Vue03_vue属性_数据代理_第15张图片

 

你可能感兴趣的:(vue.js,javascript,前端)