近期在看Vue3的源碼,看完后也根據(jù)一些閱讀文檔的時候的注釋,打算手寫實現(xiàn)模擬vue3的核心代碼,作為讀書筆記,方便后續(xù)面試的時候進行復習
你需要掌握的知識點
- Proxy & Reflect
- WeakMap
reactive 的實現(xiàn)
typescript
import { isObject } from '@vue/shared'
import { mutableHandlers, ReactiveFlags } from './basicHandler'
// 收集全局的響應式對象,key為傳入的target,value為其代理對象
const reactiveMap = new WeakMap()
export function reactive(target) {
// reactive只能接收對象類型
if (!isObject(target)) return
// 避免傳入一個已經(jīng)代理過的對象
// 未代理之前,target.__v_isReactive 為 undefined,代理過,則為true。
// 詳情看 mutableHandlers
if (target[ReactiveFlags.IS_REACTIVE]) {
return target
}
// 避免對同一個對象進行多次代理
const reactiveValue = reactiveMap.get(target)
if (reactiveValue) {
return reactiveValue
}
const proxy = new Proxy(target, mutableHandlers)
reactiveMap.set(target, proxy)
return proxy
}
mutableHandlers 的實現(xiàn)
import { track, trigger } from './effect'
import { isObject } from '@vue/shared'
import { reactive } from './reactive'
export enum ReactiveFlags {
IS_REACTIVE = '__v_isReactive'
}
export const mutableHandlers = {
get(target, key, receiver) {
if (key === ReactiveFlags.IS_REACTIVE) {
return true
}
// 收集依賴
// Fernando: 現(xiàn)在不需要知道他是怎么實現(xiàn)的,你只需要知道他在這里的操作就是收集依賴。后續(xù)章節(jié)我會補上
track(target, 'get', key)
const result = Reflect.get(target, key, receiver)
if (isObject(result)) {
// 實現(xiàn)深度代理,相較于vue2在初期階段就遞歸進行數(shù)據(jù)劫持,性能更好,取值的時候再進行代理
return reactive(result)
}
return result
},
set(target, key, value, receiver) {
const oldValue = target[key]
const result = Reflect.set(target, key, value, receiver)
if (oldValue !== value) {
// 觸發(fā)更新依賴相關的effect
// Fernando: 現(xiàn)在你不需要知道他是怎么實現(xiàn)的,你只需要知道他在這里會去觸發(fā)更新即可
trigger(target, 'set', key, value, oldValue)
}
return result
}
}
以上則為 vue3 對象代理的部分骨架代碼,后續(xù)我會持續(xù)更新,github搶先看
https://github.com/Fernando-lu/fernando-vue