forked from cuixiaorui/mini-vue
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1 parent
348f97b
commit f26ff79
Showing
4 changed files
with
100 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { effect } from "../src/effect"; | ||
import { ref } from "../src/ref"; | ||
describe("ref", () => { | ||
it("should be reactive", () => { | ||
const a = ref(1); | ||
let dummy; | ||
let calls = 0; | ||
effect(() => { | ||
calls++; | ||
dummy = a.value; | ||
}); | ||
expect(calls).toBe(1); | ||
expect(dummy).toBe(1); | ||
a.value = 2; | ||
expect(calls).toBe(2); | ||
expect(dummy).toBe(2); | ||
// same value should not trigger | ||
a.value = 2; | ||
expect(calls).toBe(2); | ||
expect(dummy).toBe(2); | ||
}); | ||
|
||
it("should make nested properties reactive", () => { | ||
const a = ref({ | ||
count: 1, | ||
}); | ||
let dummy; | ||
effect(() => { | ||
dummy = a.value.count; | ||
}); | ||
expect(dummy).toBe(1); | ||
a.value.count = 2; | ||
expect(dummy).toBe(2); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { trackEffects, triggerEffects } from "./effect"; | ||
import { createDep } from "./dep"; | ||
import { isObject, hasChanged } from "../../shared"; | ||
import { reactive } from "./reactive"; | ||
|
||
export class RefImpl { | ||
private _rawValue: any; | ||
private _value: any; | ||
public dep; | ||
|
||
constructor(value) { | ||
this._rawValue = value; | ||
// 看看value 是不是一个对象,如果是一个对象的话 | ||
// 那么需要用 reactive 包裹一下 | ||
this._value = convert(value); | ||
this.dep = createDep(); | ||
} | ||
|
||
get value() { | ||
// 收集依赖 | ||
trackRefValue(this); | ||
return this._value; | ||
} | ||
|
||
set value(newValue) { | ||
// 当新的值不等于老的值的话, | ||
// 那么才需要触发依赖 | ||
if (hasChanged(newValue, this._rawValue)) { | ||
// 更新值 | ||
this._value = convert(newValue); | ||
this._rawValue = newValue; | ||
// 触发依赖 | ||
triggerRefValue(this); | ||
} | ||
} | ||
} | ||
|
||
export function ref(value) { | ||
return createRef(value); | ||
} | ||
|
||
function convert(value) { | ||
return isObject(value) ? reactive(value) : value; | ||
} | ||
|
||
function createRef(value) { | ||
const refImpl = new RefImpl(value); | ||
|
||
return refImpl; | ||
} | ||
|
||
function triggerRefValue(ref) { | ||
triggerEffects(ref.dep); | ||
} | ||
|
||
function trackRefValue(ref) { | ||
trackEffects(ref.dep); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters