feat(core): 实现响应性系统的核心功能
- 添加 effect 函数用于创建响应性副作用 - 实现 ReactiveEffect 类来管理响应性执行 - 添加 track 函数用于依赖收集 - 添加 trigger 函数用于触发依赖更新 - 在 baseHandlers 中实现 Proxy 的 get 和 set 拦截器 - 将 effect 导出到 vue 包的入口文件 - 添加 dev 脚本用于监听构建 - 更新示例文件展示响应性功能的使用 - 修复 README.md 中代码块格式问题
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
# .prettierrc
|
||||
|
||||
```
|
||||
{
|
||||
"semi": false,// 结尾无分号
|
||||
"singleQuote": true,// 单引号
|
||||
@@ -7,3 +8,4 @@
|
||||
"trailingComma": "none",// 不添加尾随逗号
|
||||
"arrowParens": "avoid"// 省略箭头函数的括号
|
||||
}
|
||||
```
|
||||
@@ -3,6 +3,7 @@
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "rollup -c -w",
|
||||
"build": "rollup -c",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
|
||||
@@ -1,4 +1,32 @@
|
||||
/**
|
||||
* 响应性的handler
|
||||
*/
|
||||
export const mutableHandlers: ProxyHandler<object> = {}
|
||||
import { track, trigger } from './effect'
|
||||
|
||||
const get = createGetter()
|
||||
function createGetter() {
|
||||
return function get(target: object, key: string | symbol, receiver: object) {
|
||||
const res = Reflect.get(target, key, receiver)
|
||||
track(target, key)
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
const set = createSetter()
|
||||
function createSetter() {
|
||||
return function set(
|
||||
target: object,
|
||||
key: string | symbol,
|
||||
value: unknown,
|
||||
receiver: object
|
||||
) {
|
||||
const result = Reflect.set(target, key, value, receiver)
|
||||
trigger(target, key, value)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
export const mutableHandlers: ProxyHandler<object> = {
|
||||
get,
|
||||
set
|
||||
}
|
||||
|
||||
33
packages/reactivity/src/effect.ts
Normal file
33
packages/reactivity/src/effect.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
export function effect<T = any>(fn: () => T) {
|
||||
const _effect = new ReactiveEffect(fn)
|
||||
_effect.run()
|
||||
}
|
||||
|
||||
export let activeEffect: ReactiveEffect | undefined
|
||||
|
||||
export class ReactiveEffect<T = any> {
|
||||
constructor(public fn: () => T) {}
|
||||
run() {
|
||||
activeEffect = this
|
||||
return this.fn()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 收集依赖
|
||||
* @param target
|
||||
* @param key
|
||||
*/
|
||||
export function track(target: object, key: unknown) {
|
||||
console.log('收集依赖 track')
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发依赖
|
||||
* @param target
|
||||
* @param key
|
||||
* @param newValue
|
||||
*/
|
||||
export function trigger(target: object, key: unknown, newValue: unknown) {
|
||||
console.log('触发依赖 trigger')
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
export { reactive } from './reactive'
|
||||
export { effect } from './effect'
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
<script src="../../dist/vue.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
<script>
|
||||
const { reactive } = Vue
|
||||
console.log(reactive)
|
||||
const { reactive,effect } = Vue
|
||||
const obj=reactive({
|
||||
name:'张三'
|
||||
})
|
||||
console.log(obj)
|
||||
effect(()=>{
|
||||
document.querySelector('#app').innerText=obj.name
|
||||
})
|
||||
</script>
|
||||
</html>
|
||||
@@ -1 +1 @@
|
||||
export { reactive } from '@vue/reactivity'
|
||||
export { reactive, effect } from '@vue/reactivity'
|
||||
|
||||
Reference in New Issue
Block a user