From d3fea3f2449a9377899ca55c940c45dcb179338f Mon Sep 17 00:00:00 2001 From: dj Date: Tue, 3 Feb 2026 18:14:33 +0800 Subject: [PATCH] =?UTF-8?q?feat(reactivity):=20=E5=AE=9E=E7=8E=B0=E5=93=8D?= =?UTF-8?q?=E5=BA=94=E5=BC=8F=E7=B3=BB=E7=BB=9F=E5=9F=BA=E7=A1=80=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 baseHandlers.ts 文件,定义响应性 handler - 在 reactivity 模块中导出 reactive 函数 - 将 vue 主入口改为导出 reactive,移除测试代码 - 添加 reactive.html 示例文件用于测试响应式功能 - 实现 reactive 函数,支持创建复杂数据类型的响应式对象 - 使用 WeakMap 缓存代理对象,避免重复代理 --- packages/reactivity/src/baseHandlers.ts | 4 ++ packages/reactivity/src/index.ts | 2 +- packages/reactivity/src/reactive.ts | 41 +++++++++++++++++++ .../vue/examples/reactivity/reactive.html | 19 +++++++++ packages/vue/src/index.ts | 4 +- 5 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 packages/reactivity/src/baseHandlers.ts create mode 100644 packages/reactivity/src/reactive.ts create mode 100644 packages/vue/examples/reactivity/reactive.html diff --git a/packages/reactivity/src/baseHandlers.ts b/packages/reactivity/src/baseHandlers.ts new file mode 100644 index 0000000..ed402aa --- /dev/null +++ b/packages/reactivity/src/baseHandlers.ts @@ -0,0 +1,4 @@ +/** + * 响应性的handler + */ +export const mutableHandlers: ProxyHandler = {} diff --git a/packages/reactivity/src/index.ts b/packages/reactivity/src/index.ts index 9571437..33ea422 100644 --- a/packages/reactivity/src/index.ts +++ b/packages/reactivity/src/index.ts @@ -1 +1 @@ -let msg = '测试' +export { reactive } from './reactive' diff --git a/packages/reactivity/src/reactive.ts b/packages/reactivity/src/reactive.ts new file mode 100644 index 0000000..645217d --- /dev/null +++ b/packages/reactivity/src/reactive.ts @@ -0,0 +1,41 @@ +import { mutableHandlers } from './baseHandlers' + +/** + * 响应性Map缓存对象 + * key:target + * val:proxy + */ +export const reactiveMap = new WeakMap() + +/** + * 为复杂数据类型, 创建响应式对象 + * @param target 被代理的对象 + * @returns 代理对象 + */ +export function reactive(target: object) { + return createReactiveObject(target, mutableHandlers, reactiveMap) +} + +/** + * 创建响应式对象 + * @param target 被代理对象 + * @param baseHandlers handler + * @param proxyMap + */ +function createReactiveObject( + target: object, + baseHandlers: ProxyHandler, + proxyMap: WeakMap +) { + //如果该实例已经被代理, 则直接读取即可 + const existingProxy = proxyMap.get(target) + if (existingProxy) { + return existingProxy + } + //未被代理则生成proxy实例 + const proxy = new Proxy(target, baseHandlers) + + //缓存代理对象 + proxyMap.set(target, proxy) + return proxy +} diff --git a/packages/vue/examples/reactivity/reactive.html b/packages/vue/examples/reactivity/reactive.html new file mode 100644 index 0000000..7748aa4 --- /dev/null +++ b/packages/vue/examples/reactivity/reactive.html @@ -0,0 +1,19 @@ + + + + + Document + + + + + + + \ No newline at end of file diff --git a/packages/vue/src/index.ts b/packages/vue/src/index.ts index 2b01101..66bdf72 100644 --- a/packages/vue/src/index.ts +++ b/packages/vue/src/index.ts @@ -1,3 +1 @@ -import { isArray } from '@vue/shared' - -console.log(isArray([])) +export { reactive } from '@vue/reactivity'