vue3源码之reactive

内容分享5小时前发布
0 0 0

响应式对象reactive

何为响应式对象,在我看来就是一个可以进行拦截的对象,vue2采用的是Object.definePropertyvue3采用的是Proxy

单测

创建
src/reactivity/test/reactive.spec.ts

import {reactive} from '../reactive'
describe("reactive", () => {
  it("happy path", () => {
    const origin = {
      foo: 1
    }
    const obj = reactive(origin)
    expect(obj).not.toBe(origin)
    expect(obj.foo).toBe(1)
  })
})

在vue3里,直接通过一个reactive(obj)函数创建一个proxy对象,返回的对象属性和值都和obj保持一致,但他们属于不同的两个对象。

代码实现

根据上面单测的功能点,我们开始一步步的来实现我们的reactive函数。

创建
./src/reactivity/reative.ts
文件

1、导出一个reactive函数,接收用户传入的object数据。

export function reactive (raw) {
  // write at this
}

2、返回一个Proxy实例

Proxy接收2个参数,第一个是需要劫持的object,第二个参数是一个options,这里我们只用设置getset

export function reactive (raw) {
  return new Proxy(raw, {
    get (target, key) {},
    set (target, key, value) {}
  })
}

3、处理get请求

当获取这个响应式对象的某个属性时调用,target就是获取的objectkey就是获取的对象属性名称。

例如:obj.name,target代表obj,而key则代表name

提示:这里的Reflect.get(target, key)实则就是获取target对象的key属性的值,最后在get中返回这个值即可。

get (target, key) {
  const res = Reflect.get(target, key)
  return res
}

4、处理set赋值

当执行了赋值操作时会调用set方法,target是操作的对象,key是操作对象的属性名称,value是赋值。

Reflect.set(target, key, value)即是给target对象的key属性赋值value,该执行结果是boolean,即代表赋值成功与否。

set (target, key, value) {
  const res = Reflect.set(target, key, value)
  return res
}

到这里,我们就成功创建了一个响应式对象,给这个响应式对象添加了set,和get操作。

总结

最后我们再一起来回顾一下这一节我们实现的代码及功能,在reactive.ts中我们导出了reactive函数,自身接收一个obj作为参数,并基于obj返回一个proxy对象,我们还简单的处理了一下proxygetset请求,后面我们将会对这个proxy对象进行完善,真正达到响应式。

© 版权声明

相关文章

暂无评论

none
暂无评论...