主要思路
封装createGetter 和 createSetter函数,这两个函数分别返回get 和 set方法,同时将一个布尔值作为参数传入,判断当前对象是否是readOnly的,根据这个参数对get 和 set方法做不同的处理。
一些细节点
封装createGetter 和 createSetter函数:
抽离函数:相同逻辑的代码可以将其抽离成一个函数,参数不一样就行,增加代码的可读性。
function createGetter(isReadOnly = false) {
return function get(target, key) {
const res = Reflect.get(target, key)
if (!isReadOnly) {
// 收集依赖
track(target, key)
}
return res
}
}
function createSetter() {
return function set(target, key, value) {
const res = Reflect.set(target, key, value)
// 触发依赖
trigger(target, key)
return res
}
}
抽离baseHandle, 逻辑代码相同的抽离成一个函数,增加代码的可读性
import { mutableHandlers, readonlyHandlers } from "./baseHandlers"
export function reactive(raw) {
return createActiveObject(raw, mutableHandlers)
}
export function readonly(raw) {
return createActiveObject(raw, readonlyHandlers)
}
function createActiveObject(raw: any, baseHandlers: any) {
return new Proxy(raw, baseHandlers)
}
缓存:避免每次读或写数据的时候都要重新创建getter 和 setter函数,只让 get 或 set 函数在初始化的时候创建一次,后续需要使用get 或者 set 方法的时候复用这个函数就行。
(优化之前的代码)
const get = createGetter()
const set = createGetter()
const readonlyGet = createGetter(true)
export const mutableHandlers = {
get,
set,
}
export const readonlyHandlers = {
get: readonlyGet,
set(target, key, value) {
return true
},
}
(优化之后的代码)
const get = createGetter()
const set = createGetter()
const readonlyGet = createGetter(true)
export const mutableHandlers = {
get,
set,
}
export const readonlyHandlers = {
get: readonlyGet,
set(target, key, value) {
return true
},
}