mirror of https://github.com/vuejs/core.git
feat: ref peek
This commit is contained in:
parent
56be3dd4db
commit
cc326a72d2
|
@ -1150,4 +1150,54 @@ describe('reactivity/computed', () => {
|
|||
const t2 = performance.now()
|
||||
expect(t2 - t1).toBeLessThan(process.env.CI ? 100 : 30)
|
||||
})
|
||||
|
||||
describe('peek', () => {
|
||||
it('should return updated value', () => {
|
||||
const value = reactive<{ foo?: number }>({})
|
||||
const cValue = computed(() => value.foo)
|
||||
expect(cValue.peek()).toBe(undefined)
|
||||
value.foo = 1
|
||||
expect(cValue.peek()).toBe(1)
|
||||
})
|
||||
|
||||
it('should compute lazily', () => {
|
||||
const value = reactive<{ foo?: number }>({})
|
||||
const getter = vi.fn(() => value.foo)
|
||||
const cValue = computed(getter)
|
||||
|
||||
// lazy
|
||||
expect(getter).not.toHaveBeenCalled()
|
||||
|
||||
expect(cValue.peek()).toBe(undefined)
|
||||
expect(getter).toHaveBeenCalledTimes(1)
|
||||
|
||||
// should not compute again
|
||||
cValue.peek()
|
||||
expect(getter).toHaveBeenCalledTimes(1)
|
||||
|
||||
// should not compute until needed
|
||||
value.foo = 1
|
||||
expect(getter).toHaveBeenCalledTimes(1)
|
||||
|
||||
// now it should compute
|
||||
expect(cValue.peek()).toBe(1)
|
||||
expect(getter).toHaveBeenCalledTimes(2)
|
||||
|
||||
// should not compute again
|
||||
cValue.peek()
|
||||
expect(getter).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('should not trigger effect', () => {
|
||||
const value = reactive<{ foo?: number }>({})
|
||||
const cValue = computed(() => value.foo)
|
||||
let dummy
|
||||
effect(() => {
|
||||
dummy = cValue.peek()
|
||||
})
|
||||
expect(dummy).toBe(undefined)
|
||||
value.foo = 1
|
||||
expect(dummy).toBe(undefined)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -534,4 +534,26 @@ describe('reactivity/ref', () => {
|
|||
// @ts-expect-error internal field
|
||||
expect(objectRefValue._value).toBe(1)
|
||||
})
|
||||
|
||||
describe('peek', () => {
|
||||
it('should hold a value', () => {
|
||||
const a = ref(1)
|
||||
expect(a.peek()).toBe(1)
|
||||
a.value = 2
|
||||
expect(a.peek()).toBe(2)
|
||||
})
|
||||
|
||||
it('should not be reactive', () => {
|
||||
const a = ref(1)
|
||||
let dummy
|
||||
const fn = vi.fn(() => {
|
||||
dummy = a.peek()
|
||||
})
|
||||
effect(fn)
|
||||
expect(fn).toHaveBeenCalledTimes(1)
|
||||
expect(dummy).toBe(1)
|
||||
a.value = 2
|
||||
expect(fn).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -26,9 +26,11 @@ interface BaseComputedRef<T, S = T> extends Ref<T, S> {
|
|||
|
||||
export interface ComputedRef<T = any> extends BaseComputedRef<T> {
|
||||
readonly value: T
|
||||
peek: () => T
|
||||
}
|
||||
|
||||
export interface WritableComputedRef<T, S = T> extends BaseComputedRef<T, S> {
|
||||
peek: () => T
|
||||
[WritableComputedRefSymbol]: true
|
||||
}
|
||||
|
||||
|
@ -151,6 +153,12 @@ export class ComputedRefImpl<T = any> implements Subscriber {
|
|||
warn('Write operation failed: computed value is readonly')
|
||||
}
|
||||
}
|
||||
|
||||
peek(): T {
|
||||
refreshComputed(this)
|
||||
|
||||
return this._value
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,6 +34,10 @@ export interface Ref<T = any, S = T> {
|
|||
[RefSymbol]: true
|
||||
}
|
||||
|
||||
export interface RefWithPeek<T = any, S = T> extends Ref<T, S> {
|
||||
peek: () => T
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a value is a ref object.
|
||||
*
|
||||
|
@ -54,7 +58,9 @@ export function isRef(r: any): r is Ref {
|
|||
*/
|
||||
export function ref<T>(
|
||||
value: T,
|
||||
): [T] extends [Ref] ? IfAny<T, Ref<T>, T> : Ref<UnwrapRef<T>, UnwrapRef<T> | T>
|
||||
): [T] extends [Ref]
|
||||
? IfAny<T, Ref<T>, T>
|
||||
: RefWithPeek<UnwrapRef<T>, UnwrapRef<T> | T>
|
||||
export function ref<T = any>(): Ref<T | undefined>
|
||||
export function ref(value?: unknown) {
|
||||
return createRef(value, false)
|
||||
|
@ -66,6 +72,10 @@ export type ShallowRef<T = any, S = T> = Ref<T, S> & {
|
|||
[ShallowRefMarker]?: true
|
||||
}
|
||||
|
||||
export type ShallowRefWithPeek<T = any, S = T> = ShallowRef<T, S> & {
|
||||
peek: () => T
|
||||
}
|
||||
|
||||
/**
|
||||
* Shallow version of {@link ref}.
|
||||
*
|
||||
|
@ -156,6 +166,10 @@ class RefImpl<T = any> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
peek() {
|
||||
return this._rawValue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue