Vue响应式原理的解析过程

本文仅用于个人学习过程中的总结巩固

html

<div id="app">
  {{name}} <!-- 发布者name属性内的订阅者1 -->
  {{name}} <!-- 发布者name属性内的订阅者2 -->
  {{name}} <!-- 发布者name属性内的订阅者3 -->
  {{age}} <!-- 发布者age属性内的订阅者1 -->
</div>

js

const app = new Vue({
  el: '#app',
  data: {
    name: 'sky', // 发布者-name属性
    age: 18 // 发布者-age属性
  }
})

当我们在项目开发中修改了data数据后,页面马上就能响应,这是如何做到的呢?

发布者与订阅者机制

// 发布者的类,包含多个方法
class Dep{
  constructor() {
  	// subs = subscribers,订阅者列表
    this.subs = []
  }
  // 增加一个订阅者
  addSub(watcher) {
    this.subs.push(watcher)
  }
  // 当监听的发布者变化时,调用此方法以更新所有订阅者
  notify() {
    this.subs.forEach(item => {
      item.update()
    })
  }
}
// 订阅者的类
class Watcher {
  constructor(name) {
    this.name = name
  }
  // 更新当前订阅者数据
  update() {
    console.log(this.name + '发生update')
  }
}

Observer及Compile

new Vue()

  • Observer
  • Compile

创建vue实例时,vue实例会将el及data分发给Observer及Compile进行处理

- Observer

用于监听劫持所有data属性,会进行以下处理

// 遍历data里所有属性
Object.keys(data).forEach(key => {
  let value = data[key]
  // Object.defineProperty方法,改变属性值
  Object.defineProperty(data, key, {
    set(newValue) { // 属性值改变时即调用此方法
      console.log('监听' + key + '改变')
      value = newValue
    },
    get() { // 获取属性值时即调用此方法
      console.log('获取' + key + '的值')
      return value
    }
  })
})

- Compile

解析el模板中的指令

<div id="app">
  {{name}} <!-- 发布者name属性内的订阅者1 -->
  {{name}} <!-- 发布者name属性内的订阅者2 -->
  {{name}} <!-- 发布者name属性内的订阅者3 -->
  {{age}} <!-- 发布者age属性内的订阅者1 -->
</div>

1、Observer会对每一个data内的属性都创建一个Dep对象(“发布者”)
2、Compile解析el模板中的指令,如果指令有对应符合的data属性名,则先会创建一个Watcher的实例对象,并将其作为“订阅者”加入该Dep对象(“发布者”)的subs数组中
3、当data内属性的值发生变化时,监听的Observer会调用其中的set方法,在set方法里再调用notify方法,notify方法则是将当前Dep对象内的所有“订阅者”循环并执行每一个自身的update方法以进行数据更新。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值