• 双向数据绑定为vue2核心技术并且比较复杂,这里讲述下实现过程及简略源码
  • 在创立vue实例的时候vue做了三件事
  1. 属性监听(Observe)
  2. 属性代理(Obagent)
  3. 末班编译(Compile)
  • Observe: 为vue date上的属性增加get,set办法( 通过递归调用Object.defineProperty )
  • 注:此时每个vue实例上的属性被拜访或批改都会触发身上的getset办法,此为vue的数据劫持
  • Obagent:通过Object.defineProperty来监听间接拜访和设置vm上的对象此时去拜访或设置vm data 上的对象
  • 注:Obagent只须要劫持顶层data上的数据

Compile:

  1. 考录到循环渲染耗费性能 vue采取文档碎片的形式编译模板
    注:文档碎片争议比拟大 新版非ie文档碎片的性能没问题,思考到这一点自己倡议应用模板字符串拼接的形式,在这里兼容了ie
  2. 获取vue实例根节点(#app),挂在到vue实例上,通过递归的形式将根节点上所有子节点增加到文档碎片中(创立个空的文档碎片够细了吧)
  3. 在递归增加文档碎片的过程中将vue data 上的值替换掉{{}},和v-model的值
  4. 最初将文档碎片增加到根节点中

此时实现了vue对实例上数据的渲染

  • vue 存在两个类 别离是 收集订阅者(Dep)和公布订阅者(Watcher)
  • Dep:存储这所有的订阅者(watcher) 一个长期的target 和 增加wacher/更新调用watcher的办法
  • watcher:属性有 vue实例 key 回调函数 和一个更新本人的办法

收集所有的watcher

  1. 在模板编译的时,在每次dom与vue 实例 data 上数据的响应 都会创立个watcher
  2. 在每次创立watcher的时候,watcher指向Dep的target 而后通过触发get办法将watcher增加到sub汇合中( 触发get办法vue采纳一种取巧的形式,在每次创立watcher会携带个key,通过reduce万金油的办法去链式拜访这个值触发get办法,失去想要的后果在把dep上的target清空 )
  3. 在页面数据批改的时候( set被触发时 )调用dep的notify 区循环调用watcher上的update( update 的回调会承受一个newValue,通过更新node节点达到双向绑定的成果 )