vue3中reactive源码浅析

本文深入探讨了vue3.0.5中reactive模块的源码,从测试用例出发,了解响应式数据的设计和实现。重点分析了reactive方法,解释了如何通过Proxy的get和set拦截器实现响应式,并涉及依赖收集和触发机制,同时提到了computed和watch在响应式系统中的角色。
摘要由CSDN通过智能技术生成

reactive源码学习

这次clone下来的vue3.0.5的代码,学习reactive模块相关内容。了解vue3中的响应式数据的设计、实现。首先进入到源码中,可以很方便的找到reactivity模块。打开这个模块之后呢?要如何下手就一脸懵逼了,然后猛然发现了__test__文件夹,灵机一动从单测入手不就可以快速的知道这个模块下主要暴露出的api会有哪些,具体的功能会有哪些了吗?于是就愉快的开始阅读单测相关的内容。

测试用例

第一个相关单测:

test('Object', () => {
   
  const original = {
    foo: 1 }                       // 原始数据
  const observed = reactive(original)               // 响应式数据
  expect(observed).not.toBe(original)               // 响应式数据和原始数据不能是同一个引用
  expect(isReactive(observed)).toBe(true)
  expect(isReactive(original)).toBe(false)
  // get
  expect(observed.foo).toBe(1)                      // 获取到的值与原始数据保持一致
  // has
  expect('foo' in observed).toBe(true)              // 具有原始数据的key值
  // ownKeys
  expect(Object.keys(observed)).toEqual(['foo'])    // key值是自有可见的
})

第二个相关单测:

// 嵌套数据的响应式
test('nested reactives', () => {
   
  const original = {
   
    nested: {
   
      foo: 1
    },
    array: [{
    bar: 2 }]
  }
  const observed = reactive(original)
  expect(isReactive(observed.nested)).toBe(true) // 嵌套对象响应式
  expect(isReactive(observed.array)).toBe(true) // 嵌套数组响应式
  expect(isReactive(observed.array[0])).toBe(true) // 嵌套数组中的对象依然响应式
})

第三个及第四个相关单测:
这里的两个单测就说明了vue3中的响应式数据操作可以直接在proxy数据上进行操作即可。

// 响应式数据上改变的数据需要修改到原始数据上
test('observed value should proxy mutations to original (Object)', () => {
   
  const original: any = {
    foo: 1 }
  const observed = reactive(original)
  // set 在代理对象上设置了新数据,原始对象上也会新增数据
  observed.bar = 1
  expect(observed.bar).toBe(1)
  expect(original.bar).toBe(1)
  // delete 在代理对象上删除了数据,原始对象也会删除对应的数据
  delete observed.foo
  expect('foo' in observed).toBe(false)
  expect('foo' in original).toBe(false)
})
// 原始数据上修改的数据需要反映到响应式数据中
test('original value change should reflect in observed value (Object)', () => {
   
  const original: any = {
    foo: 1 }
  const observed = reactive(original)
  // set
  original.bar = 1
  expect(original.bar).toBe(1)
  expect(observed.bar).toBe(1)
  // delete
  delete original.foo
  expect('foo' in original).toBe(false)
  expect('foo' in observed).toBe(false)
})

单测文件看到这里也对proxy的响应式数据有了一个基本了解,现在可以去看看在以上测试用例中一直出现的一个关键性方法reactive了。从用例上就可以看出来这个方法就是定义响应式数据的方法。通过用例的引入语句import { reactive, isReactive, toRaw, markRaw } from '../src/reactive'知道这个方法是从reactive.ts文件中引入的。

reactive源码

// reactive.ts
export function reactive(target: object) {
   
  // if trying to observe a readonly proxy, return the readonly version.
  if (target && (target as Target)[ReactiveFlags.IS_READONLY]) {
   
    return target
  }
  
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值