feat(reactivity): 实现响应式系统基础功能
- 新增 baseHandlers.ts 文件,定义响应性 handler - 在 reactivity 模块中导出 reactive 函数 - 将 vue 主入口改为导出 reactive,移除测试代码 - 添加 reactive.html 示例文件用于测试响应式功能 - 实现 reactive 函数,支持创建复杂数据类型的响应式对象 - 使用 WeakMap 缓存代理对象,避免重复代理
This commit is contained in:
4
packages/reactivity/src/baseHandlers.ts
Normal file
4
packages/reactivity/src/baseHandlers.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
/**
|
||||||
|
* 响应性的handler
|
||||||
|
*/
|
||||||
|
export const mutableHandlers: ProxyHandler<object> = {}
|
||||||
@@ -1 +1 @@
|
|||||||
let msg = '测试'
|
export { reactive } from './reactive'
|
||||||
|
|||||||
41
packages/reactivity/src/reactive.ts
Normal file
41
packages/reactivity/src/reactive.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { mutableHandlers } from './baseHandlers'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应性Map缓存对象
|
||||||
|
* key:target
|
||||||
|
* val:proxy
|
||||||
|
*/
|
||||||
|
export const reactiveMap = new WeakMap<object, any>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为复杂数据类型, 创建响应式对象
|
||||||
|
* @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<any>,
|
||||||
|
proxyMap: WeakMap<object, any>
|
||||||
|
) {
|
||||||
|
//如果该实例已经被代理, 则直接读取即可
|
||||||
|
const existingProxy = proxyMap.get(target)
|
||||||
|
if (existingProxy) {
|
||||||
|
return existingProxy
|
||||||
|
}
|
||||||
|
//未被代理则生成proxy实例
|
||||||
|
const proxy = new Proxy(target, baseHandlers)
|
||||||
|
|
||||||
|
//缓存代理对象
|
||||||
|
proxyMap.set(target, proxy)
|
||||||
|
return proxy
|
||||||
|
}
|
||||||
19
packages/vue/examples/reactivity/reactive.html
Normal file
19
packages/vue/examples/reactivity/reactive.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Document</title>
|
||||||
|
<script src="../../dist/vue.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
const { reactive } = Vue
|
||||||
|
console.log(reactive)
|
||||||
|
const obj=reactive({
|
||||||
|
name:'张三'
|
||||||
|
})
|
||||||
|
console.log(obj)
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
@@ -1,3 +1 @@
|
|||||||
import { isArray } from '@vue/shared'
|
export { reactive } from '@vue/reactivity'
|
||||||
|
|
||||||
console.log(isArray([]))
|
|
||||||
|
|||||||
Reference in New Issue
Block a user