export interface ComputedRef<T = any> extends WritableComputedRef<T> {
readonly value: T
+ defer?: (fn: () => void) => void
}
export interface WritableComputedRef<T> extends Ref<T> {
set: ComputedSetter<T>
}
+type ComputedScheduler = (fn: () => void) => void
+let scheduler: ComputedScheduler | undefined
+
+/**
+ * Set a scheduler for deferring computed computations
+ */
+export const setComputedScheduler = (s: ComputedScheduler | undefined) => {
+ scheduler = s
+}
+
class ComputedRefImpl<T> {
public dep?: Set<ReactiveEffect> = undefined
private readonly _setter: ComputedSetter<T>,
isReadonly: boolean
) {
+ let deferFn: () => void
+ let scheduled = false
this.effect = new ReactiveEffect(getter, () => {
if (!this._dirty) {
this._dirty = true
- triggerRefValue(this)
+ if (scheduler) {
+ if (!scheduled) {
+ scheduled = true
+ scheduler(
+ deferFn ||
+ (deferFn = () => {
+ scheduled = false
+ if (this._dirty) {
+ this._dirty = false
+ const newValue = this.effect.run()!
+ if (this._value !== newValue) {
+ this._value = newValue
+ triggerRefValue(this)
+ }
+ } else {
+ triggerRefValue(this)
+ }
+ })
+ )
+ }
+ } else {
+ triggerRefValue(this)
+ }
}
})
this[ReactiveFlags.IS_READONLY] = isReadonly
import { isArray } from '@vue/shared'
import { ComponentInternalInstance, getComponentName } from './component'
import { warn } from './warning'
+import { setComputedScheduler } from '@vue/reactivity'
+
+// set scheduler for computed
+setComputedScheduler(queueJob)
export interface SchedulerJob extends Function {
id?: number