wip: value()
This commit is contained in:
parent
453cdcd600
commit
02421dbe62
@ -3,6 +3,7 @@ import { OperationTypes } from './operations'
|
|||||||
import { track, trigger } from './effect'
|
import { track, trigger } from './effect'
|
||||||
import { LOCKED } from './lock'
|
import { LOCKED } from './lock'
|
||||||
import { isObject } from '@vue/shared'
|
import { isObject } from '@vue/shared'
|
||||||
|
import { isValue } from './value'
|
||||||
|
|
||||||
const hasOwnProperty = Object.prototype.hasOwnProperty
|
const hasOwnProperty = Object.prototype.hasOwnProperty
|
||||||
|
|
||||||
@ -18,6 +19,9 @@ function createGetter(isImmutable: boolean) {
|
|||||||
if (typeof key === 'symbol' && builtInSymbols.has(key)) {
|
if (typeof key === 'symbol' && builtInSymbols.has(key)) {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
if (isValue(res)) {
|
||||||
|
return res.value
|
||||||
|
}
|
||||||
track(target, OperationTypes.GET, key)
|
track(target, OperationTypes.GET, key)
|
||||||
return isObject(res)
|
return isObject(res)
|
||||||
? isImmutable
|
? isImmutable
|
||||||
@ -38,6 +42,10 @@ function set(
|
|||||||
value = unwrap(value)
|
value = unwrap(value)
|
||||||
const hadKey = hasOwnProperty.call(target, key)
|
const hadKey = hasOwnProperty.call(target, key)
|
||||||
const oldValue = target[key]
|
const oldValue = target[key]
|
||||||
|
if (isValue(oldValue)) {
|
||||||
|
oldValue.value = value
|
||||||
|
return true
|
||||||
|
}
|
||||||
const result = Reflect.set(target, key, value, receiver)
|
const result = Reflect.set(target, key, value, receiver)
|
||||||
// don't trigger if target is something up in the prototype chain of original
|
// don't trigger if target is something up in the prototype chain of original
|
||||||
if (target === unwrap(receiver)) {
|
if (target === unwrap(receiver)) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { OperationTypes } from './operations'
|
import { OperationTypes } from './operations'
|
||||||
import { Dep, KeyToDepMap, targetMap } from './state'
|
import { Dep, targetMap } from './state'
|
||||||
|
|
||||||
export interface ReactiveEffect {
|
export interface ReactiveEffect {
|
||||||
(): any
|
(): any
|
||||||
@ -84,8 +84,10 @@ export function track(
|
|||||||
if (type === OperationTypes.ITERATE) {
|
if (type === OperationTypes.ITERATE) {
|
||||||
key = ITERATE_KEY
|
key = ITERATE_KEY
|
||||||
}
|
}
|
||||||
// keyMap must exist because only an observed target can call this function
|
let depsMap = targetMap.get(target)
|
||||||
const depsMap = targetMap.get(target) as KeyToDepMap
|
if (depsMap === void 0) {
|
||||||
|
targetMap.set(target, (depsMap = new Map()))
|
||||||
|
}
|
||||||
let dep = depsMap.get(key as string | symbol)
|
let dep = depsMap.get(key as string | symbol)
|
||||||
if (!dep) {
|
if (!dep) {
|
||||||
depsMap.set(key as string | symbol, (dep = new Set()))
|
depsMap.set(key as string | symbol, (dep = new Set()))
|
||||||
@ -111,7 +113,11 @@ export function trigger(
|
|||||||
key?: string | symbol,
|
key?: string | symbol,
|
||||||
extraInfo?: any
|
extraInfo?: any
|
||||||
) {
|
) {
|
||||||
const depsMap = targetMap.get(target) as KeyToDepMap
|
const depsMap = targetMap.get(target)
|
||||||
|
if (depsMap === void 0) {
|
||||||
|
// never been tracked
|
||||||
|
return
|
||||||
|
}
|
||||||
const effects = new Set()
|
const effects = new Set()
|
||||||
const computedRunners = new Set()
|
const computedRunners = new Set()
|
||||||
if (type === OperationTypes.CLEAR) {
|
if (type === OperationTypes.CLEAR) {
|
||||||
|
@ -28,6 +28,7 @@ export { ReactiveEffect, ReactiveEffectOptions, DebuggerEvent }
|
|||||||
export { OperationTypes } from './operations'
|
export { OperationTypes } from './operations'
|
||||||
export { computed, ComputedGetter } from './computed'
|
export { computed, ComputedGetter } from './computed'
|
||||||
export { lock, unlock } from './lock'
|
export { lock, unlock } from './lock'
|
||||||
|
export { value, isValue } 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)\]$/
|
||||||
|
27
packages/observer/src/value.ts
Normal file
27
packages/observer/src/value.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { track, trigger } from './effect'
|
||||||
|
import { OperationTypes } from './operations'
|
||||||
|
|
||||||
|
const knownValues = new WeakSet()
|
||||||
|
|
||||||
|
export interface Value<T> {
|
||||||
|
value: T
|
||||||
|
}
|
||||||
|
|
||||||
|
export function value<T>(raw: T): Value<T> {
|
||||||
|
const v = {
|
||||||
|
get value() {
|
||||||
|
track(v, OperationTypes.GET, '')
|
||||||
|
return raw
|
||||||
|
},
|
||||||
|
set value(newVal) {
|
||||||
|
raw = newVal
|
||||||
|
trigger(v, OperationTypes.SET, '')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
knownValues.add(v)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isValue(v: any): boolean {
|
||||||
|
return knownValues.has(v)
|
||||||
|
}
|
@ -1,17 +1,10 @@
|
|||||||
import { ComponentInstance } from './component'
|
import { ComponentInstance } from './component'
|
||||||
import { isObservable, unwrap } from '@vue/observer'
|
|
||||||
|
|
||||||
// TODO use proper implementation
|
|
||||||
function isValue(binding: any) {
|
|
||||||
return isObservable(binding) && unwrap(binding).hasOwnProperty('value')
|
|
||||||
}
|
|
||||||
|
|
||||||
export const RenderProxyHandlers = {
|
export const RenderProxyHandlers = {
|
||||||
get(target: ComponentInstance, key: string) {
|
get(target: ComponentInstance, key: string) {
|
||||||
const { state, props } = target
|
const { state, props } = target
|
||||||
if (state.hasOwnProperty(key)) {
|
if (state.hasOwnProperty(key)) {
|
||||||
const value = state[key]
|
return state[key]
|
||||||
return isValue(value) ? value.value : value
|
|
||||||
} else if (props.hasOwnProperty(key)) {
|
} else if (props.hasOwnProperty(key)) {
|
||||||
return props[key]
|
return props[key]
|
||||||
} else {
|
} else {
|
||||||
@ -34,12 +27,7 @@ export const RenderProxyHandlers = {
|
|||||||
set(target: ComponentInstance, key: string, value: any): boolean {
|
set(target: ComponentInstance, key: string, value: any): boolean {
|
||||||
const { state } = target
|
const { state } = target
|
||||||
if (state.hasOwnProperty(key)) {
|
if (state.hasOwnProperty(key)) {
|
||||||
const binding = state[key]
|
state[key] = value
|
||||||
if (isValue(binding)) {
|
|
||||||
binding.value = value
|
|
||||||
} else {
|
|
||||||
state[key] = value
|
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
|
@ -128,6 +128,7 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
} else {
|
} else {
|
||||||
if (__DEV__ && !isFunction(type) && !isObject(type)) {
|
if (__DEV__ && !isFunction(type) && !isObject(type)) {
|
||||||
// TODO warn invalid node type
|
// TODO warn invalid node type
|
||||||
|
debugger
|
||||||
}
|
}
|
||||||
processComponent(n1, n2, container, anchor)
|
processComponent(n1, n2, container, anchor)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user