vue源码分析---数据代理、数据劫持、模板解析、数据双向绑定

    准备知识点  

        1)    [].slice.call(lis): 将伪数组转换为真数组

        2)    node.nodeType: 得到节点类型
        节点类型
                                 nodeType    nodeName    nodeValue
            1、元素节点        1          大写标签名        null
            2、属性节点        2             属性名          属性值
            3、文本节点        3               #text         文本内容
            4、注释节点        8           #comment    注释内容

        3)    Object.defineProperty(obj, propName, {}): 给对象添加/修改属性(指定描述符)
                configurable: true/false  是否可以重新define
                enumerable: true/false 是否可以枚举(for..in / keys())
                value: 指定初始值
                writable: true/false value是否可以修改

                get: 回调函数, 用来得到当前属性值
                set: 回调函数, 用来监视当前属性值的变化

        4)    Object.keys(obj): 得到对象自身可枚举的属性名的数组

        for       js当中给的最基本语法  它是专门用来遍历数组的  这个效率一般  但是可以使用break和continue
        for...in  js当中给的遍历对象的语法  它的效率是最低的,因为不但要遍历自身的属性还要去遍历原型
        forEach   它是数组的一个方法,效率是最高的,专门用来遍历数组,但是没办法使用break和continue
        for...of 它是遍历可迭代对象的,具有迭代器方法的数据才能使用,它效率比for好,也可以使用break和continue

        最好以后禁用for...in 遍历对象

        遍历对象全部改为
        Object.keys(obj).forEach(key => {
            console.log(key,obj[key])
        })

        5)    obj.hasOwnProperty(prop): 判断prop是否是obj自身的属性
        一般都会配合for...in
        for..in遍历的时候遍历自己的属性和原型里面的,我们想要知道遍历的这个属性是不是自身的
        就要采用obj.hasOwnProperty(prop) 

        6)    documentfragment 
            是一个容器,这个容器本身进入不了页面,它内部的所有东西会进去页面,在内存中干活,批量更新
          1、可以把原来的元素的子节点,转移到documentfragment 节点当中,原来的里面就没有了
          2、去处理documentfragment 中的子元素节点数据
          3、最后把documentfragment 节点 追加到原来的元素当中

数据代理(MVVM文件)

       使用Object.defineProperty在vm身上添加和data当中同名的属性
       访问vm身上的属性会调用getter,返回的其实是data中的同名属性值
        修改vm身上的属性会调用setter,修改的其实是data中的同名属性数据


数据监视/数据劫持

            做了两件事:
            1、根据data中的属性,对应都创建一个dep对象

            2、会把data当中的数据变为响应式数据,原理还是添加getter和setter

            数据劫持(数据监视)
              通过Object.defineProperty对data所有的属性修改响应式(添加getter和setter)
              如果用户访问vm身上的属性,返回data的同名属性值,同时就会访问data的同名属性,
              data的同名属性是有getter的,返回data的同名属性值
              如果用户修改vm身上的属性,修改的是data的同名属性,同时修改data的同名属性
              data同名属性也是有setter的,把数给data的同名属性(同时修改页面上的数据)

            setter内部其实做了三个事
                    1、修改自己的数据
                    2、把修改的新数据也递归调用变为响应式
                    3、通知页面去修改数据

模板解析和数据绑定    

        单独看插值
            第一步:从模板当中找到表达式  {{msg}}
            第二步:根据从模板中找到的表达式msg,从vm的_data当中获取和msg同名的属性值
            第三步:找到text对应的更新器
            第四步:将找到的同名属性值把模板当中的{{msg}} 替换          
            第五步:为当前这个表达式创建watcher,并且和同名属性的dep进行关联绑定

   

单独看一般指令: 一般指令v-text  v-html v-class
       第一步:从模板当中找到指令的表达式以及指令名  msg 和 text
       第二步:根据从模板中找到的表达式msg,从vm的_data当中获取和msg同名的属性值
       第三步:根据指令名找到对应的更新器
       第四步:将找到的同名属性值添加到使用指令的元素内容当中,并删除元素对应的指令属性
       第五步:为当前这个表达式创建watcher,并且和同名属性的dep进行关联绑定

        //无论是插值语法解析还是一般指令解析
        //解析完成以后,对于每个表达式都会创建一个watcher对象
        //但是事件指令解析完成没有创建watcher,因为事件不能改变
        watcher:{
            cp:cp //回调函数
            vm:vm //vm对象
            exp:exp //‘msg’
            depIds:{0:dep},
            value://当前表达式的值
        }

            

单独看事件指令:(它没有替换之说,触发事件直接调用回调函数就完了)
            第一步:从模板当中找到指令的表达式以及指令名  test 和 on:click
            第二步:根据on:click判断是不是事件指令
            第三步:以表达式test 从vm当中的methods里面找到对应的回调函数
                          以指令名冒号后面的东西找到事件类型
            第四步:将使用这个指令的元素绑定事件,同时把事件回调函数的this永久指向vm对象,最终删除指令属性

            
        
数据单向绑定(插值语法和普通指令才会存在单向数据绑定,事件指令没有)
   初始化数据展示,说的就是模板解析
   模板解析解析完成,页面上的数据才会从文档碎片还给dom
   在模板解析的过程当中,除了初始化数据解析展示,还做了模板表达式和data的属性之间的绑定
 (watcher和dep两种小弟的关系)

前面我们在数据劫持的时候为每个属性都创建了一个dep对象
            {
                id:0,
                subs:[watcher] //后期存储模板表达式的watcher
            }            

修改数据之后,我们的data里面的属性数据会改变
接着会调用这个属性的setter,setter里面会通知当前这个属性的dep当中所有的watcher
每个watcher都有一个回调函数,会调用这个回调函数去更新页面对应的数据

    

数据双向绑定:

            双向数据绑定依赖于单向数据绑定
            双向数据绑定其实就是多了一个事件 input事件,触发事件修改data的值

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值