Skip to content

Commit

Permalink
feat: 实现了代理数组的循环监听.
Browse files Browse the repository at this point in the history
  • Loading branch information
Zhe28 committed Mar 8, 2024
1 parent beb6f73 commit 51946bc
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 17 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@
"lint-staged": {
"*.{js,css,md}": "prettier --write"
}
}
}
21 changes: 12 additions & 9 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,24 +85,24 @@ function trigger(target, key, type, newValue) {
*/
const effectsToRun = new Set();
effects &&
effects.forEach((effect) => {
effectsToRun.add(effect);
effects.forEach((effectFn) => {
effectsToRun.add(effectFn);
});

// for ... in 循环时, 因为增加和删除都会影响对象的长度和 for 循环的次数,要重新执行一遍副作用函数
if (type === triggerType.ADD || type === triggerType.DELETE) {
iterateEffects &&
iterateEffects.forEach((effect) => {
effectsToRun.add(effect);
iterateEffects.forEach((effectFn) => {
effectsToRun.add(effectFn);
});
}
// 当类型是 triggerType.add 时, 并且是数组时,将函数加入到effectsToRun中运行
if (type === triggerType.ADD && Array.isArray(target)) {
const lengthEffects = depsMap.get("length");
lengthEffects &&
lengthEffects.forEach((effect) => {
if (effect !== activeEffect) {
effectsToRun.add(effect);
lengthEffects.forEach((effectFn) => {
if (effectFn !== activeEffect) {
effectsToRun.add(effectFn);
}
});
}
Expand Down Expand Up @@ -187,7 +187,8 @@ function createReactive(obj, isShallow = false, isReadonly = false) {
}

// 只读属性不触发收集依赖
if (!isReadonly) {
// 或者 property 属性类型不是 symbol 值时,不触发依赖 ( for ... of 遍历时 property属性是 symbol [@@Symbol.iterator])
if (!isReadonly && typeof p !== "symbol") {
track(target, p);
}

Expand All @@ -210,7 +211,9 @@ function createReactive(obj, isShallow = false, isReadonly = false) {
},
// 拦截 for ... in 的响应式变量
ownKeys(target) {
track(target, ITERATE_KEY);
// for ... in 遍历时。检测对象是否是数组,如果是数组,使用 length 属性建立连接
// 否则 ITERATE_KEY 属性建立连接
track(target, Array.isArray(target) ? "length" : "ITERATE_KEY");
return Reflect.ownKeys(target);
},
// 拦截 delete 操作符
Expand Down
22 changes: 17 additions & 5 deletions src/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,14 +199,26 @@ import { computed, effect, reactive, readonly, shallowReactive, shallowReadonly,

/**
* todo: 代理数组
* 数组索引与 length :
* 数组索引与 length
* 数组遍历
*/

// 数组索引与 length
const arr = reactive(["foo"]);
// // 数组索引与 length
// const arr = reactive(["foo"]);
// effect(() => {
// console.log(arr[0]);
// });
//
// arr[0] = "bar";
// arr.length = 0;

// for ... in 数组遍历
const arr = reactive([1, 2, 3]);
effect(() => {
console.log(arr.length);
for (const res in arr) {
console.log(res);
}
});

arr[2] = "bar";
// arr[3] = "bar";
arr.length = 0;
4 changes: 2 additions & 2 deletions src/note.excalidraw
Git LFS file not shown

0 comments on commit 51946bc

Please sign in to comment.