vue2数据响应式原理

文章详细介绍了Vue框架中的数据劫持机制,包括构造函数、Observer、Compile和Watcher类的作用。Vue2使用Object.defineProperty进行数据劫持,存在只能劫持对象属性、无法监听属性新增删除及数组方法的局限。Vue3则采用Proxy,能更有效地处理深度嵌套属性和数组变化的监听。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、总结

关键:发布订阅模式 + 数据劫持
实现上关注:new Vue主流程 + 两个类

二、new Vue的主流程

class Vue {
  constructor(options) {
    this.$data = options.data
    // 数据劫持的方法
    Observe(this.$data)
    // 末班编译的方法
    Compile(options.el, this)
  }
}
function Observe(obj) {
  const dep = new Dep()
  Object.keys(obj).forEach((key) => {
    get() {
      // Dep.target就是watcher
      dep.addSub(Dep.target)
    }
    set(n) {
      Observe(n)
      dep.notify()
    }
  })
}
function Compile() {
  // 在模板编译中添加watcher
  new Watcher(vm, key, () => {})
}

三、两个类

1、Watcher订阅者的类
2、Dep依赖收集的类(收集watcher订阅者的类)

class watcher {
  constructor(vm, key, cb) {
    this.vm = vm
    this.key = key
    // 把watcher实例放到Dep类的静态属性上
    Dep.target = this
  }
  update() {
    this.cb(this.key)
  }
}
class Dep {
  constructor() {
    this.subs = []
  }
  addSub(watcher) {
    this.subs.push(watcher)
  }
  notify() {
    this.subs.forEach(watcher => {
      watcher.update()
    })
  }
}

四、vue2与vue3中的数据劫持对比

vue2中使用defineProperty的缺点

1、只能劫持对象的属性,需要对data进行遍历劫持;如果属性多层嵌套,就会进行递归,导致调用栈的溢出
2、不能监听对象新增和删除属性
解决:
this.$set(this.obj, 'name', 'jim')
this.$delete(this.obj, 'name')
3、无法监听数组的方法
vue自己封装了一些数组的方法(push、pop、sort...)
4、直接使用下标修改数组;直接修改数组length
// 1是指下标位置
this.$set(this.arr, 1, 'sss')
--------------------------------------------------------------------------
vue3使用的Proxy

1、有多层嵌套的情况,只会在访问属性的时候递归
2、3、4全都能监听

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值