]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor: adjust reactivity structure
authorEvan You <yyx990803@gmail.com>
Tue, 11 Jun 2019 16:03:50 +0000 (00:03 +0800)
committerEvan You <yyx990803@gmail.com>
Tue, 11 Jun 2019 16:03:50 +0000 (00:03 +0800)
packages/reactivity/__tests__/value.spec.ts
packages/reactivity/src/effect.ts
packages/reactivity/src/index.ts
packages/reactivity/src/state.ts

index f72026fd76f7153438da26f47466e6321f69aa7f..3ad687fd16ee5e27875e06785ef133454570dbc2 100644 (file)
@@ -1,5 +1,4 @@
-import { value } from '../src/value'
-import { effect, state } from '../src/index'
+import { value, effect, state } from '../src/index'
 
 describe('observer/value', () => {
   it('should hold a value', () => {
index 9d9295c022957de10615c6eb59a7fa4d0f09382b..51adc4a5ce30b9211da354192e94ba529b2cf225 100644 (file)
@@ -1,5 +1,6 @@
 import { OperationTypes } from './operations'
 import { Dep, targetMap } from './state'
+import { EMPTY_OBJ } from '@vue/shared'
 
 export interface ReactiveEffect {
   (): any
@@ -38,7 +39,31 @@ export const activeReactiveEffectStack: ReactiveEffect[] = []
 
 export const ITERATE_KEY = Symbol('iterate')
 
-export function createReactiveEffect(
+export function effect(
+  fn: Function,
+  options: ReactiveEffectOptions = EMPTY_OBJ
+): ReactiveEffect {
+  if ((fn as ReactiveEffect).isEffect) {
+    fn = (fn as ReactiveEffect).raw
+  }
+  const effect = createReactiveEffect(fn, options)
+  if (!options.lazy) {
+    effect()
+  }
+  return effect
+}
+
+export function stop(effect: ReactiveEffect) {
+  if (effect.active) {
+    cleanup(effect)
+    if (effect.onStop) {
+      effect.onStop()
+    }
+    effect.active = false
+  }
+}
+
+function createReactiveEffect(
   fn: Function,
   options: ReactiveEffectOptions
 ): ReactiveEffect {
@@ -72,7 +97,7 @@ function run(effect: ReactiveEffect, fn: Function, args: any[]): any {
   }
 }
 
-export function cleanup(effect: ReactiveEffect) {
+function cleanup(effect: ReactiveEffect) {
   const { deps } = effect
   if (deps.length) {
     for (let i = 0; i < deps.length; i++) {
index 28f895198d793b6a9b9b1c8f320bbda9172a78cd..3bc0572012135b46ba5b7c847931c1d3b22bcf1a 100644 (file)
-import { isObject, EMPTY_OBJ } from '@vue/shared'
-import { mutableHandlers, immutableHandlers } from './baseHandlers'
-
-import {
-  mutableCollectionHandlers,
-  immutableCollectionHandlers
-} from './collectionHandlers'
-
-import {
-  targetMap,
-  observedToRaw,
-  rawToObserved,
-  immutableToRaw,
-  rawToImmutable,
-  immutableValues,
-  nonReactiveValues
+export { value, isValue, Value, UnwrapValue } from './value'
+export {
+  state,
+  isState,
+  immutableState,
+  isImmutableState,
+  toRaw,
+  markImmutable,
+  markNonReactive
 } from './state'
-
-import {
-  createReactiveEffect,
-  cleanup,
+export { computed, ComputedValue } from './computed'
+export {
+  effect,
+  stop,
   ReactiveEffect,
   ReactiveEffectOptions,
   DebuggerEvent
 } from './effect'
-
-import { UnwrapValue } from './value'
-
-export { ReactiveEffect, ReactiveEffectOptions, DebuggerEvent }
-export { OperationTypes } from './operations'
-export { computed, ComputedValue } from './computed'
 export { lock, unlock } from './lock'
-export { value, isValue, Value, UnwrapValue } from './value'
-
-const collectionTypes: Set<any> = new Set([Set, Map, WeakMap, WeakSet])
-const observableValueRE = /^\[object (?:Object|Array|Map|Set|WeakMap|WeakSet)\]$/
-
-const canObserve = (value: any): boolean => {
-  return (
-    !value._isVue &&
-    !value._isVNode &&
-    observableValueRE.test(Object.prototype.toString.call(value)) &&
-    !nonReactiveValues.has(value)
-  )
-}
-
-type ObservableFactory = <T>(target?: T) => UnwrapValue<T>
-
-export const state = ((target: any = {}): any => {
-  // if trying to observe an immutable proxy, return the immutable version.
-  if (immutableToRaw.has(target)) {
-    return target
-  }
-  // target is explicitly marked as immutable by user
-  if (immutableValues.has(target)) {
-    return immutableState(target)
-  }
-  return createObservable(
-    target,
-    rawToObserved,
-    observedToRaw,
-    mutableHandlers,
-    mutableCollectionHandlers
-  )
-}) as ObservableFactory
-
-export const immutableState = ((target: any = {}): any => {
-  // value is a mutable observable, retrive its original and return
-  // a readonly version.
-  if (observedToRaw.has(target)) {
-    target = observedToRaw.get(target)
-  }
-  return createObservable(
-    target,
-    rawToImmutable,
-    immutableToRaw,
-    immutableHandlers,
-    immutableCollectionHandlers
-  )
-}) as ObservableFactory
-
-function createObservable(
-  target: any,
-  toProxy: WeakMap<any, any>,
-  toRaw: WeakMap<any, any>,
-  baseHandlers: ProxyHandler<any>,
-  collectionHandlers: ProxyHandler<any>
-) {
-  if (!isObject(target)) {
-    if (__DEV__) {
-      console.warn(`value is not observable: ${String(target)}`)
-    }
-    return target
-  }
-  // target already has corresponding Proxy
-  let observed = toProxy.get(target)
-  if (observed !== void 0) {
-    return observed
-  }
-  // target is already a Proxy
-  if (toRaw.has(target)) {
-    return target
-  }
-  // only a whitelist of value types can be observed.
-  if (!canObserve(target)) {
-    return target
-  }
-  const handlers = collectionTypes.has(target.constructor)
-    ? collectionHandlers
-    : baseHandlers
-  observed = new Proxy(target, handlers)
-  toProxy.set(target, observed)
-  toRaw.set(observed, target)
-  if (!targetMap.has(target)) {
-    targetMap.set(target, new Map())
-  }
-  return observed
-}
-
-export function effect(
-  fn: Function,
-  options: ReactiveEffectOptions = EMPTY_OBJ
-): ReactiveEffect {
-  if ((fn as ReactiveEffect).isEffect) {
-    fn = (fn as ReactiveEffect).raw
-  }
-  const effect = createReactiveEffect(fn, options)
-  if (!options.lazy) {
-    effect()
-  }
-  return effect
-}
-
-export function stop(effect: ReactiveEffect) {
-  if (effect.active) {
-    cleanup(effect)
-    if (effect.onStop) {
-      effect.onStop()
-    }
-    effect.active = false
-  }
-}
-
-export function isState(value: any): boolean {
-  return observedToRaw.has(value) || immutableToRaw.has(value)
-}
-
-export function isImmutableState(value: any): boolean {
-  return immutableToRaw.has(value)
-}
-
-export function toRaw<T>(observed: T): T {
-  return observedToRaw.get(observed) || immutableToRaw.get(observed) || observed
-}
-
-export function markImmutable<T>(value: T): T {
-  immutableValues.add(value)
-  return value
-}
-
-export function markNonReactive<T>(value: T): T {
-  nonReactiveValues.add(value)
-  return value
-}
+export { OperationTypes } from './operations'
index eee65d22f6c47833251c71163a5cbe051e9b96a0..0f990ebbeb56bd2d52b4f9b18b7920310db49026 100644 (file)
@@ -1,3 +1,12 @@
+import { isObject } from '@vue/shared'
+import { mutableHandlers, immutableHandlers } from './baseHandlers'
+
+import {
+  mutableCollectionHandlers,
+  immutableCollectionHandlers
+} from './collectionHandlers'
+
+import { UnwrapValue } from './value'
 import { ReactiveEffect } from './effect'
 
 // The main WeakMap that stores {target -> key -> dep} connections.
@@ -9,12 +18,119 @@ export type KeyToDepMap = Map<string | symbol, Dep>
 export const targetMap: WeakMap<any, KeyToDepMap> = new WeakMap()
 
 // WeakMaps that store {raw <-> observed} pairs.
-export const rawToObserved: WeakMap<any, any> = new WeakMap()
-export const observedToRaw: WeakMap<any, any> = new WeakMap()
-export const rawToImmutable: WeakMap<any, any> = new WeakMap()
-export const immutableToRaw: WeakMap<any, any> = new WeakMap()
+const rawToObserved: WeakMap<any, any> = new WeakMap()
+const observedToRaw: WeakMap<any, any> = new WeakMap()
+const rawToImmutable: WeakMap<any, any> = new WeakMap()
+const immutableToRaw: WeakMap<any, any> = new WeakMap()
 
 // WeakSets for values that are marked immutable or non-reactive during
 // observable creation.
-export const immutableValues: WeakSet<any> = new WeakSet()
-export const nonReactiveValues: WeakSet<any> = new WeakSet()
+const immutableValues: WeakSet<any> = new WeakSet()
+const nonReactiveValues: WeakSet<any> = new WeakSet()
+
+const collectionTypes: Set<any> = new Set([Set, Map, WeakMap, WeakSet])
+const observableValueRE = /^\[object (?:Object|Array|Map|Set|WeakMap|WeakSet)\]$/
+
+const canObserve = (value: any): boolean => {
+  return (
+    !value._isVue &&
+    !value._isVNode &&
+    observableValueRE.test(Object.prototype.toString.call(value)) &&
+    !nonReactiveValues.has(value)
+  )
+}
+
+type ObservableFactory = <T>(target?: T) => UnwrapValue<T>
+
+export const state = ((target: any = {}): any => {
+  // if trying to observe an immutable proxy, return the immutable version.
+  if (immutableToRaw.has(target)) {
+    return target
+  }
+  // target is explicitly marked as immutable by user
+  if (immutableValues.has(target)) {
+    return immutableState(target)
+  }
+  return createObservable(
+    target,
+    rawToObserved,
+    observedToRaw,
+    mutableHandlers,
+    mutableCollectionHandlers
+  )
+}) as ObservableFactory
+
+export const immutableState = ((target: any = {}): any => {
+  // value is a mutable observable, retrive its original and return
+  // a readonly version.
+  if (observedToRaw.has(target)) {
+    target = observedToRaw.get(target)
+  }
+  return createObservable(
+    target,
+    rawToImmutable,
+    immutableToRaw,
+    immutableHandlers,
+    immutableCollectionHandlers
+  )
+}) as ObservableFactory
+
+function createObservable(
+  target: any,
+  toProxy: WeakMap<any, any>,
+  toRaw: WeakMap<any, any>,
+  baseHandlers: ProxyHandler<any>,
+  collectionHandlers: ProxyHandler<any>
+) {
+  if (!isObject(target)) {
+    if (__DEV__) {
+      console.warn(`value is not observable: ${String(target)}`)
+    }
+    return target
+  }
+  // target already has corresponding Proxy
+  let observed = toProxy.get(target)
+  if (observed !== void 0) {
+    return observed
+  }
+  // target is already a Proxy
+  if (toRaw.has(target)) {
+    return target
+  }
+  // only a whitelist of value types can be observed.
+  if (!canObserve(target)) {
+    return target
+  }
+  const handlers = collectionTypes.has(target.constructor)
+    ? collectionHandlers
+    : baseHandlers
+  observed = new Proxy(target, handlers)
+  toProxy.set(target, observed)
+  toRaw.set(observed, target)
+  if (!targetMap.has(target)) {
+    targetMap.set(target, new Map())
+  }
+  return observed
+}
+
+export function isState(value: any): boolean {
+  return observedToRaw.has(value) || immutableToRaw.has(value)
+}
+
+export function isImmutableState(value: any): boolean {
+  return immutableToRaw.has(value)
+}
+
+export function toRaw<T>(observed: T): T {
+  return observedToRaw.get(observed) || immutableToRaw.get(observed) || observed
+}
+
+export function markImmutable<T>(value: T): T {
+  immutableValues.add(value)
+  return value
+}
+
+export function markNonReactive<T>(value: T): T {
+  nonReactiveValues.add(value)
+  return value
+}