wip: computed
This commit is contained in:
parent
02421dbe62
commit
cf86e32575
0
packages/observer/__tests__/value.spec.ts
Normal file
0
packages/observer/__tests__/value.spec.ts
Normal file
@ -1,15 +1,16 @@
|
|||||||
import { effect } from './index'
|
import { effect } from './index'
|
||||||
import { ReactiveEffect, activeReactiveEffectStack } from './effect'
|
import { ReactiveEffect, activeReactiveEffectStack } from './effect'
|
||||||
|
import { knownValues } from './value'
|
||||||
|
|
||||||
export interface ComputedGetter<T = any> {
|
export interface ComputedValue<T> {
|
||||||
(): T
|
readonly value: T
|
||||||
effect: ReactiveEffect
|
readonly effect: ReactiveEffect
|
||||||
}
|
}
|
||||||
|
|
||||||
export function computed<T, C = null>(
|
export function computed<T, C = null>(
|
||||||
getter: (this: C, ctx: C) => T,
|
getter: (this: C, ctx: C) => T,
|
||||||
context?: C
|
context?: C
|
||||||
): ComputedGetter<T> {
|
): ComputedValue<T> {
|
||||||
let dirty: boolean = true
|
let dirty: boolean = true
|
||||||
let value: any = undefined
|
let value: any = undefined
|
||||||
const runner = effect(() => getter.call(context, context), {
|
const runner = effect(() => getter.call(context, context), {
|
||||||
@ -18,7 +19,12 @@ export function computed<T, C = null>(
|
|||||||
dirty = true
|
dirty = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const computedGetter = (() => {
|
// mark effect as computed so that it gets priority during trigger
|
||||||
|
runner.computed = true
|
||||||
|
const computedValue = {
|
||||||
|
// expose effect so computed can be stopped
|
||||||
|
effect: runner,
|
||||||
|
get value() {
|
||||||
if (dirty) {
|
if (dirty) {
|
||||||
value = runner()
|
value = runner()
|
||||||
dirty = false
|
dirty = false
|
||||||
@ -28,12 +34,10 @@ export function computed<T, C = null>(
|
|||||||
// This should also apply for chained computed properties.
|
// This should also apply for chained computed properties.
|
||||||
trackChildRun(runner)
|
trackChildRun(runner)
|
||||||
return value
|
return value
|
||||||
}) as ComputedGetter
|
}
|
||||||
// expose effect so computed can be stopped
|
}
|
||||||
computedGetter.effect = runner
|
knownValues.add(computedValue)
|
||||||
// mark effect as computed so that it gets priority during trigger
|
return computedValue
|
||||||
runner.computed = true
|
|
||||||
return computedGetter
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function trackChildRun(childRunner: ReactiveEffect) {
|
function trackChildRun(childRunner: ReactiveEffect) {
|
||||||
|
@ -26,9 +26,9 @@ import {
|
|||||||
|
|
||||||
export { ReactiveEffect, ReactiveEffectOptions, DebuggerEvent }
|
export { ReactiveEffect, ReactiveEffectOptions, DebuggerEvent }
|
||||||
export { OperationTypes } from './operations'
|
export { OperationTypes } from './operations'
|
||||||
export { computed, ComputedGetter } from './computed'
|
export { computed, ComputedValue } from './computed'
|
||||||
export { lock, unlock } from './lock'
|
export { lock, unlock } from './lock'
|
||||||
export { value, isValue } from './value'
|
export { value, isValue, Value } from './value'
|
||||||
|
|
||||||
const collectionTypes: Set<any> = new Set([Set, Map, WeakMap, WeakSet])
|
const collectionTypes: Set<any> = new Set([Set, Map, WeakMap, WeakSet])
|
||||||
const observableValueRE = /^\[object (?:Object|Array|Map|Set|WeakMap|WeakSet)\]$/
|
const observableValueRE = /^\[object (?:Object|Array|Map|Set|WeakMap|WeakSet)\]$/
|
||||||
|
@ -1,20 +1,25 @@
|
|||||||
import { track, trigger } from './effect'
|
import { track, trigger } from './effect'
|
||||||
import { OperationTypes } from './operations'
|
import { OperationTypes } from './operations'
|
||||||
|
import { isObject } from '@vue/shared'
|
||||||
|
import { observable } from './index'
|
||||||
|
|
||||||
const knownValues = new WeakSet()
|
export const knownValues = new WeakSet()
|
||||||
|
|
||||||
export interface Value<T> {
|
export interface Value<T> {
|
||||||
value: T
|
value: T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const convert = (val: any): any => (isObject(val) ? observable(val) : val)
|
||||||
|
|
||||||
export function value<T>(raw: T): Value<T> {
|
export function value<T>(raw: T): Value<T> {
|
||||||
|
raw = convert(raw)
|
||||||
const v = {
|
const v = {
|
||||||
get value() {
|
get value() {
|
||||||
track(v, OperationTypes.GET, '')
|
track(v, OperationTypes.GET, '')
|
||||||
return raw
|
return raw
|
||||||
},
|
},
|
||||||
set value(newVal) {
|
set value(newVal) {
|
||||||
raw = newVal
|
raw = convert(newVal)
|
||||||
trigger(v, OperationTypes.SET, '')
|
trigger(v, OperationTypes.SET, '')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user