Vue系列二十四:源码解析-数据绑定

数据劫持与数据绑定
1、数据绑定(model==>View):
(1)、一旦更新了data中的某个属性数据, 所有界面上直接使用或间接使用了此属性的节点都会更新(更新)。
2、数据劫持
(1)、数据劫持是vue中用来实现数据绑定的一种技术。
(2)、基本思想: 通过defineProperty()来监视data中所有属性(任意层次)数据的变化, 一旦变化就去更新界面。
3、四个重要对象
(1)、Observer
  用来对data所有属性数据进行劫持的构造函数。
  给data中所有属性重新定义属性描述(get/set)。
  为data中的每个属性创建对应的dep对象。
(2)、Dep(Depend)
  data中的每个属性(所有层次)都对应一个dep对象。
  创建的时机:
    在初始化define data中各个属性时创建对应的dep对象。
    在data中的某个属性值被设置为新的对象时。
  对象的结构:

    {
   	    id, // 每个dep都有一个唯一的id
        subs //包含n个对应watcher的数组(subscribes的简写)
    }

  subs属性说明:
    当一个watcher被创建时, 内部会将当前watcher对象添加到对应的dep对象的subs中。
    当此data属性的值发生改变时, 所有subs中的watcher都会收到更新的通知, 从而最终更新对应的界面。
(3)、Compile
  用来解析模板页面的对象的构造函数(一个实例)。
  利用compile对象解析模板页面。
  每解析一个表达式(非事件指令)都会创建一个对应的watcher对象, 并建立watcher与dep的关系。
  complie与watcher关系: 一对多的关系。
(4)、Watcher
  模板中每个非事件指令或表达式都对应一个watcher对象。
  监视当前表达式数据的变化。
  创建的时机: 在初始化编译模板时。
  对象的组成:

    {
         vm,  //vm对象
         exp, //对应指令的表达式
         cb, //当表达式所对应的数据发生改变的回调函数
         value, //表达式当前的值
         depIds //表达式中各级属性所对应的dep对象的集合对象
                 //属性名为dep的id, 属性值为dep
	}

(5)、 总结: dep与watcher的关系: 多对多
  一个data中的属性对应对应一个dep, 一个dep中可能包含多个watcher(模板中有几个表达式使用到了属性)。
  模板中一个非事件表达式对应一个watcher, 一个watcher中可能包含多个dep(表达式中包含了几个data属性)。
  数据绑定使用到2个核心技术:
     defineProperty()
    消息订阅与发布
4、双向数据绑定
(1)、双向数据绑定是建立在单向数据绑定(model==>View)的基础之上的。
(2)、双向数据绑定的实现流程:
  在解析v-model指令时, 给当前元素添加input监听
  当input的value发生改变时, 将最新的值赋值给当前表达式所对应的data属性

<body>
<!--
    1. 数据绑定
      * 初始化显示: 页面(表达式/指令)能从data读取数据显示 (编译/解析)
      * 更新显示: 更新data中的属性数据==>页面更新
  -->
<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的属性进行数据劫持时创建的
  个数:与data中的属性一一对应
  Dep的结构:
    id: 标识
    subs:[] n个相关的watcher对象的容器
Watcher
  创建时间:初始化的解析大括号表达式与一般指令时创建
  个数:与模板中表达式(不包含事件指令)一一对应
  Watcher的结构:
    this.cb = cb;  // 用于更新界面的回调
    this.vm = vm;  // vm
    this.exp = exp;  // 对应表达式
    this.depIds = {};  // 相关的n个dep的容器对象
    this.value = this.get(); // 当前表达式对应的value
Dep与Watcher之间的关系:多对多关系
  一个dep中对应多个watcher:同一个属性在模板中多次使用  {{name}} v-text="name"
  一个watcher中对应多个dep:多层表达式   {{a.b.c}}
  建立关系的方法:data中属性的get()方法
  建立时间:初始化的解析模块中的表达式创建watcher对象时
  vm.name = 'xxx' 执行流程:
    1、data中的name属性值变化
    2、调用name的set()方法
    3、通知dep
    4、通知所有相关的watcher
    5、调用cb()回调函数
    6、调用updater方法更新界面
-->


<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: 'feifei',
      wife: {
        name: 'feifei2',
        age: 28
      }
    },
    methods: {
      //更新数据
      update () {
        this.name = 'xinxin'
      }
    }
  })
</script>
</body>
<body>
<div id="test">
  <input type="text" v-model="msg">
  <p>{{msg}}</p>
</div>

<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: {
      msg: 'hello'
    }
  })
</script>
</body>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值