zoukankan      html  css  js  c++  java
  • Vue----源码学习-基本实现原理(数据代理、模板编译、数据绑定的实现、双向数据绑定)

    最近在学习Vue的源码,之前刚开始接触Vue的时候也是我刚开始学习开发,我看完了Vue官方文档就去网上找Vue源码的资料来看,看的是一脸懵逼。现在对Vue有一点了解之后再去看总于能看懂了。

    Vue作为一个MVVM框架的基本实现原理包含数据代理模板编译数据绑定、双向数据绑定

    数据代理:

    解释:用过一个对象代理对另一个对象(在前一个对象内部)中属性的操作(读/写)

    Vue数据代理:通过vm对象来代理data中所有属性的操作

    好处:更方便的操作data中的数据

    基本实现流程:

      1.通过Object.defineProperty()给vm添加与data对象属性对应的属性描述符

      2.所有添加的属性都添加了getter/setter函数

      3.通过getter/setter内部去操作data中对应的属性数据

    模板编译:

    Vue模板编译:将Vue的大括号表达式和指令(一般指令、事件指令)初始化显示

    基本流程:

      1.去除el的所有子节点,添加到一个新的fragment对象中

      2.对fragment中的所有层次子节点进行递归编译处理

        a.对大括号表达式文本进行编译

        b.对节点指令属性进行编译(包含一般指令与事件指令

      3.将编译完成之后的fragment添加到el中

    编译大括号表达式

      1.根据正则表达式得到匹配出的表达式字符串:子匹配/RegExp.$1

      2.从data中取出表达式对应的属性值

      3.将属性值设置为文本节点的textcontent

    编译事件指令

      1.从指令名中取出事件名

      2.根据指令的值(表达式)从methods中得到对应的事件处理函数对象

      3.给当前元素点绑定指令事件名和回调函数的dom事件监听

      4.指令编译完成后,移出此指令属性

    编译一般指令

      1.得到指令名和指令值(表达式)指令名通常为通常为text/html/class

      2.从data中根据得到的表达式取出对应的值

      3.根据指令确定需要操作元素节点的什么属性

        a.v-text--->textContent

        b.v-html--->innerHTML

        c.v-class--->className

      4.将得到的表达式的值设置到对应的属性上

      5.移出元素的指令属性

    数据绑定:

    效果:一旦更新了data中的某个属性数据,所有界面上直接使用或间接使用了此属性的节点都会更新

    实现:是有数据劫持技术实现的数据绑定

    数据劫持:

      1.数据劫持是Vue中实现数据绑定的一种技术

      2.基本思想:通过defineProperty()来监视data中所有属性(所有层次)的变化,一旦改变就去更新界面

    四个重要对象:

      1.Observer:

        a.用来对data所有属性数据进行劫持的构造函数

        b.给data中所有属性重新定义属性描述(get/set)

        c.给data中的每个属性创建对应的dep对象

      2.dep(depend)

        a.data中的每个属性(所有层次)都对应一个dep对象

        b.创建时机:

          * 在定义data中各个属性时创建对应的dep对象

          * 在data中的某个属性值被设置为新的对象时

        c.对象的结构:

          {id://每个dep都有一个唯一的ID

           subs://包含n个对应watcher的数组(subscribes的简写)}

        d.subs属性说明:

          * 当watcher被创建时,内部将当前watcher对象添加到对应的dep对象的subs中

          * 在此data竖向的值发生改变时,subs中所有的watcher都会受到更新的通知,从而更新页面

      3.compiler

        a.用来编译模板页面的对象的构造函数(一个实例)

        b.利用compile对象来编译模板页面

        c.没编译一个表达式(非事件指令)都会创建一个对应的watcher对象,并建立watcher与dep的关系

        d.complie与watcher的关系:一对多的关系

      4.watcher

        a.模板中每个非事件指令或表达式都对应一个watcher对象

        b.监视当前表达式数据的裱花

        c.创建时间:在初始化编译模板时

        d.对象的属性:

        {

          vm, //vm对象

          exp, //对应指令的表达式

          cb, //当表达式所对应的数据发生改变时的回调函数

          value, //表达式当前的值

          depIds, //表达式中各级属性所对应的drp对象的集合对象

              //属性名为dep的id,属性值为dep

          }

      5.总结:

        a.data中的一个属性对应一个dep,一个dep中可能包含多个watcher(模板中有多少个表达式用到了同一属性)

        b.模板中一个非事件表达式对应一个watcher,一个watcher中可能包含多个dep(表达式是多层a.b)

        c.数据绑定使用到两个核心技术

          * defineProperty()

          * 消息订阅与发布

    MVVM结构图:

    现在我们根据图再来看看整个Vue的基本实现原理

    初始化视图:

    创建一个vm对象->创建observer(劫持/监视data里面所有的属性),同时为每一个属性创建dep(与data中的属性一一对应)

    创建一个vm对象->创建compile(编译模板中的指令与大括号表达式)->调用updater(初始化视图),同时为表达式创建对应的watcher并绑定更新的函数->添加订阅者(将watcher添加到对应的dep的subs属性中,也就是建立两者的关系)

    更新视图:

    更新vm对象的属性->通知cbserver的set方法->通知dep->通知所有相关的watcher->调用updataer去更新视图

    双向数据绑定:

      1.双向数据绑定建立在单向数据绑定(model==>View)的基础上的

      2.双向数据绑定的实现流程:

        a.在解析v-model指令时,给当前元素添加input监听

        b.当input的value发生改变时,将最新的值赋值给当前表达式所对应的data属性

  • 相关阅读:
    poj 2728 Desert King(最小比率生成树,迭代法)
    HDU
    hud 2089 不要62 (数位dp)
    食物链(带全并查集)
    docNet基础学完感想
    zoj 1081 (改进的弧长算法)(转)
    zoj 1962 How Many Fibs?(字符串化为数字处理)
    zoj 1109 zoj 1109 Language of FatMouse(字典树)
    iOS开发网络数据之AFNetworking使用
    iOS 使用AFNetworking
  • 原文地址:https://www.cnblogs.com/si-dian/p/12850926.html
Copyright © 2011-2022 走看看