53 lines
1.7 KiB
TypeScript
53 lines
1.7 KiB
TypeScript
import { shallowReadonly, shallowRef, watchEffect } from 'vue';
|
|
import type { ShallowRef, WatchOptionsBase } from 'vue';
|
|
|
|
export type ComputedEagerOptions = Pick<WatchOptionsBase, 'flush' | 'onTrack' | 'onTrigger'>;
|
|
|
|
export type ComputedEagerReturn<T>
|
|
= Readonly<ShallowRef<T>>;
|
|
|
|
/**
|
|
* @name computedEager
|
|
* @category Reactivity
|
|
* @description Eager (non-lazy) computed value backed by a `watchEffect`-driven
|
|
* `shallowRef`. Unlike `computed`, the getter runs immediately and on every
|
|
* dependency change rather than lazily on read, so the cached value is always
|
|
* up to date. Best for cheap derived values that are read in many places.
|
|
*
|
|
* @param {() => T} getter The effect function deriving the value
|
|
* @param {ComputedEagerOptions} [options={}] Watch options (`flush` defaults to `'sync'`)
|
|
* @returns {Readonly<ShallowRef<T>>} A readonly shallow ref holding the derived value
|
|
*
|
|
* @example
|
|
* const count = ref(0);
|
|
* const isEven = computedEager(() => count.value % 2 === 0);
|
|
* isEven.value; // true
|
|
*
|
|
* @example
|
|
* // Defer recomputation until after the component update flush
|
|
* const total = computedEager(() => a.value + b.value, { flush: 'post' });
|
|
*
|
|
* @since 0.0.14
|
|
*/
|
|
export function computedEager<T>(getter: () => T, options: ComputedEagerOptions = {}): ComputedEagerReturn<T> {
|
|
const result = shallowRef<T>();
|
|
|
|
watchEffect(() => {
|
|
result.value = getter();
|
|
}, {
|
|
...options,
|
|
flush: options.flush ?? 'sync',
|
|
});
|
|
|
|
return shallowReadonly(result) as ComputedEagerReturn<T>;
|
|
}
|
|
|
|
/**
|
|
* @name eagerComputed
|
|
* @category Reactivity
|
|
* @description Alias for {@link computedEager}.
|
|
*
|
|
* @since 0.0.14
|
|
*/
|
|
export const eagerComputed = computedEager;
|