一、前言                                                                         

                       1、数据绑定原理

                               2、在数据绑定中四个重要的对象

                               3、具体实现

                                                  3.1初始化阶段

                                                  3.2建立Dep和watcher的联系阶段

                                                  3.3更新阶段

 

 

 

二、主要内容                                                                  

1、数据绑定原理

  (1)概念:一旦更新了某个数据,该节点上所有直接使用或者间接使用的节点都会更新

  (2)导致页面更新的操作

    •   方式一:原生js实现: 先获取节点对象,操作节点对象,页面发生改变
    •   方式二:vue中只需要更新data中的数据,界面中用{{msg}},或者间接使用计算属性都会导致页面发生变化

  (3)基本思想

    第一步:给data中所有的属性添加set和get方法

    第二步:用数据劫持技术实现数据绑定。思想:definedProtype去监视数据是否变化,一旦变化就去更新界面。

    第三步:举例(

        首先给vm实例中data添加xxx属性,然后会给这个实例中添加set/get方法

        然后会给data中的属性添加set/get方法

        如果用this.xxxx=xxxx去改变属性的改变,首先vm中的set先知道,然后会通知data中数据改变

        一旦data中数据改变,data中对应属性的set方法就会监视到数据改变,然后就会去更新页面

          )

 

2、在数据绑定中四个重要的对象

Observer(在数据劫持中创建)

(1)是一个对data中所有属性进行劫持的构造函数

(2)给data中的所有属性添加set/get方法(重新定义)

(3)为data中所有的属性重新创建Dep(依赖)对象

 
Dep(Depend)

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

(2)创建的时机:

*在初始化定义data中的属性的时候创建对应的dep对象

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

(3)Dep对象的结构:

{

     id,//每个dep对应唯一的id

     subs//包含n个对应的watcher的数组

}

(4)subs属性

*当watcher被创建是,内部将当前watcher对象添加到对应的Dep对象的subs里面去

*当data属性的值发生改变的时候,subs中所有的watcher都会收到更新的通知

从而更新页面

 
Compiler

(1)用来解析模板页面的对象的构造函数

(2)利用compile对象解析模板页面

(3)每解析一个表达式(非事件指令)都会创建对应的watcher对象,并建立watcher和dep之间的联系

(4)complie与watcher:一对多(一个属性可能被多次使用)

 
Watcher

(1)模板中每个非事件指令或者表达式都对应一个Watcher对象

(2)监视当前表达式数据的变化

(3)创建时机:在初始化编译模板时

(4)对象组成:

{

vm,

exp,

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

value,

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

 

}

 

(5)总结:dep与watcher的关系:多对多

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

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

       c.使用到数据劫持技术和消息订阅与发布技术

 

 

3、具体实现

 3.1初始化阶段

(1)数据劫持实现:

vue(原理)_数据绑定

 

 数据劫持:

vue(原理)_数据绑定

 

 几个重要的点:

                            ①defineReactive:进行响应式数据劫持的时候就会创建Dep对象

                            ②definedReactive里面又重新定义了data里面的对象,目的是给里面的属性添加set()/get()方法

                      ③修改的值也为对象,需要对新值进行监视

 

 

(2)模板编译:模板编译完成后会创建watcher对象

                        vue(原理)_数据绑定

 

(3)此时页面已经有如下几个对象:

vue(原理)_数据绑定

 

 

 3.2建立Dep和watcher的联系阶段

 

(1)如下图所示

vue(原理)_数据绑定

 

 

3.3更新阶段

vue(原理)_数据绑定

 

此时更新阶段完成:

                        vue(原理)_数据绑定

 4、测试代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>06_数据劫持-数据绑定</title>
  <!--
    1. 数据绑定
      * 初始化显示: 页面(表达式/指令)能从data读取数据显示 (编译/解析)
      * 更新显示: 更新data中的属性数据==>页面更新
  -->
</head>
<body>

<div id="test">
  <p>{{name}}</p>
  <p v-text="name"></p>
  <p v-text="wife.name"></p>
  <button v-on:click="update">更新</button>
</div>

<!--
dep
  与data中的属性一一对应  (4)
watcher
  与模板中一般指令/大括号表达式一一对应 (3)

1. 什么时候一个dep中关联多个watcher?
  多个指令或表达式用到了当前同一个属性  {{name}} {{name}}
2. 什么时候一个watcher中关联多个dep?
  多层表达式的watcher对应多个dep    {{a.b.c}}
-->


<script type="text/javascript" src="js/mvvm/compile.js"></script>
<script type="text/javascript" src="js/mvvm/mvvm.js"></script>
<script type="text/javascript" src="js/mvvm/observer.js"></script>
<script type="text/javascript" src="js/mvvm/watcher.js"></script>
<script type="text/javascript">
  new MVVM({
    el: '#test',
    data: {
      name: 'sadamu',  // dep0
      wife: { // dep1
        name: 'binbin', // dep2
        age: 18 // dep3
      }
    },
    methods: {
      update () {
        this.name = 'avatar'
      }
    }
  })
</script>
</body>

</html>
数据绑定.html

相关文章: