]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor: remove experimental hooks
authorEvan You <yyx990803@gmail.com>
Tue, 26 Feb 2019 23:10:08 +0000 (18:10 -0500)
committerEvan You <yyx990803@gmail.com>
Tue, 26 Feb 2019 23:10:08 +0000 (18:10 -0500)
packages/runtime-core/__tests__/hooks.spec.ts [deleted file]
packages/runtime-core/src/component.ts
packages/runtime-core/src/componentOptions.ts
packages/runtime-core/src/componentProxy.ts
packages/runtime-core/src/componentRenderUtils.ts
packages/runtime-core/src/createRenderer.ts
packages/runtime-core/src/experimental/hooks.ts [deleted file]
packages/runtime-core/src/index.ts

diff --git a/packages/runtime-core/__tests__/hooks.spec.ts b/packages/runtime-core/__tests__/hooks.spec.ts
deleted file mode 100644 (file)
index e46e5cf..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-import { useState, h, nextTick, useEffect, Component } from '../src'
-import { renderInstance, serialize, triggerEvent } from '@vue/runtime-test'
-
-describe('hooks', () => {
-  it('useState', async () => {
-    class Counter extends Component {
-      render() {
-        const [count, setCount] = useState(0)
-        return h(
-          'div',
-          {
-            onClick: () => {
-              setCount(count + 1)
-            }
-          },
-          count
-        )
-      }
-    }
-
-    const counter = await renderInstance(Counter)
-    expect(serialize(counter.$el)).toBe(`<div>0</div>`)
-
-    triggerEvent(counter.$el, 'click')
-    await nextTick()
-    expect(serialize(counter.$el)).toBe(`<div>1</div>`)
-  })
-
-  it('should be usable via hooks() method', async () => {
-    class Counter extends Component {
-      hooks() {
-        const [count, setCount] = useState(0)
-        return {
-          count,
-          setCount
-        }
-      }
-      render() {
-        const { count, setCount } = this as any
-        return h(
-          'div',
-          {
-            onClick: () => {
-              setCount(count + 1)
-            }
-          },
-          count
-        )
-      }
-    }
-
-    const counter = await renderInstance(Counter)
-    expect(serialize(counter.$el)).toBe(`<div>0</div>`)
-
-    triggerEvent(counter.$el, 'click')
-    await nextTick()
-    expect(serialize(counter.$el)).toBe(`<div>1</div>`)
-  })
-
-  it('useEffect', async () => {
-    let effect = -1
-
-    class Counter extends Component {
-      render() {
-        const [count, setCount] = useState(0)
-        useEffect(() => {
-          effect = count
-        })
-        return h(
-          'div',
-          {
-            onClick: () => {
-              setCount(count + 1)
-            }
-          },
-          count
-        )
-      }
-    }
-
-    const counter = await renderInstance(Counter)
-    expect(effect).toBe(0)
-    triggerEvent(counter.$el, 'click')
-    await nextTick()
-    expect(effect).toBe(1)
-  })
-
-  it('useEffect with empty keys', async () => {
-    // TODO
-  })
-
-  it('useEffect with keys', async () => {
-    // TODO
-  })
-
-  it('useData', () => {
-    // TODO
-  })
-
-  it('useMounted/useUnmounted/useUpdated', () => {
-    // TODO
-  })
-
-  it('useWatch', () => {
-    // TODO
-  })
-
-  it('useComputed', () => {
-    // TODO
-  })
-})
index 4cfb15695708e6ba0c8b3ae362231c4d23bfb90f..83d865522fc423a9a8a6971927cd5a11d774f4a6 100644 (file)
@@ -45,7 +45,6 @@ interface PublicInstanceMethods {
 
 export interface APIMethods<P = {}, D = {}> {
   data(): Partial<D>
-  hooks(): any
   render(props: Readonly<P>, slots: Slots, attrs: Data, parentVNode: VNode): any
 }
 
@@ -136,7 +135,6 @@ class InternalComponent implements PublicInstanceMethods {
   _queueJob: ((fn: () => void) => void) | null = null
   _isVue: boolean = true
   _inactiveRoot: boolean = false
-  _hookProps: any = null
 
   constructor(props?: object) {
     if (props === void 0) {
index 97e7db1521617f02352b07af6b30a918286a19f6..08112569e90d8773bc5050eaf44d4976e7f55286 100644 (file)
@@ -90,7 +90,6 @@ type ReservedKeys = { [K in keyof (APIMethods & LifecycleMethods)]: 1 }
 export const reservedMethods: ReservedKeys = {
   data: 1,
   render: 1,
-  hooks: 1,
   beforeCreate: 1,
   created: 1,
   beforeMount: 1,
index 0698795d11863c940c114a036270791c5c17f152..01871522e45e32293576ec554c5fda6548c1af69 100644 (file)
@@ -1,9 +1,8 @@
 import { ComponentInstance } from './component'
 import { isFunction, isReservedKey } from '@vue/shared'
-import { warn } from './warning'
 import { isRendering } from './componentRenderUtils'
-import { isObservable } from '@vue/observer'
 import { reservedMethods } from './componentOptions'
+import { warn } from './warning'
 
 const bindCache = new WeakMap()
 
@@ -37,9 +36,6 @@ const renderProxyHandlers = {
     ) {
       // computed
       return i[key]()
-    } else if ((i = target._hookProps) !== null && i.hasOwnProperty(key)) {
-      // hooks injections
-      return i[key]
     } else if (key[0] !== '_') {
       if (
         __DEV__ &&
@@ -81,16 +77,6 @@ const renderProxyHandlers = {
     if ((i = target._rawData) !== null && i.hasOwnProperty(key)) {
       target.$data[key] = value
       return true
-    } else if ((i = target._hookProps) !== null && i.hasOwnProperty(key)) {
-      if (__DEV__ && !isObservable(i)) {
-        warn(
-          `attempting to mutate a property returned from hooks(), but the ` +
-            `value is not observable.`
-        )
-      }
-      // this enables returning observable objects from hooks()
-      i[key] = value
-      return true
     } else {
       return Reflect.set(target, key, value, receiver)
     }
index 50b5508c52d4bf11517292adcb5fecdf3f3735ca..07588600b1159a59b174be814c859c801180f039 100644 (file)
@@ -4,26 +4,13 @@ import { resolveProps } from './componentProps'
 import { handleError, ErrorTypes } from './errorHandling'
 import { VNodeFlags, ChildrenFlags } from './flags'
 import { EMPTY_OBJ, isArray, isObject } from '@vue/shared'
-import { setCurrentInstance, unsetCurrentInstance } from './experimental/hooks'
 
 export let isRendering = false
 
 export function renderInstanceRoot(instance: ComponentInstance): VNode {
   let vnode
-  const {
-    $options: { hooks },
-    render,
-    $proxy,
-    $props,
-    $slots,
-    $attrs,
-    $parentVNode
-  } = instance
+  const { render, $proxy, $props, $slots, $attrs, $parentVNode } = instance
   try {
-    setCurrentInstance(instance)
-    if (hooks) {
-      instance._hookProps = hooks.call($proxy, $props) || null
-    }
     if (__DEV__) {
       isRendering = true
     }
@@ -31,7 +18,6 @@ export function renderInstanceRoot(instance: ComponentInstance): VNode {
     if (__DEV__) {
       isRendering = false
     }
-    unsetCurrentInstance()
   } catch (err) {
     handleError(err, instance, ErrorTypes.RENDER)
   }
index 38ecc854146e7aef9667202e65aae866d5cd7724..d92557cf5a61a1b9b5edd478bf31bc86875b01ce 100644 (file)
@@ -1258,7 +1258,7 @@ export function createRenderer(options: RendererOptions) {
 
     const {
       $proxy,
-      $options: { beforeMount, renderTracked, renderTriggered }
+      $options: { beforeMount, mounted, renderTracked, renderTriggered }
     } = instance
 
     instance.$forceUpdate = () => {
@@ -1318,9 +1318,6 @@ export function createRenderer(options: RendererOptions) {
           if (vnode.ref) {
             vnode.ref($proxy)
           }
-          // retrieve mounted value after initial render so that we get
-          // to inject effects in hooks
-          const { mounted } = instance.$options
           if (mounted) {
             callLifecycleHookWithHandler(mounted, $proxy, ErrorTypes.MOUNTED)
           }
diff --git a/packages/runtime-core/src/experimental/hooks.ts b/packages/runtime-core/src/experimental/hooks.ts
deleted file mode 100644 (file)
index f667b5d..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-import { ComponentInstance } from '../component'
-import { mergeLifecycleHooks, WatchOptions } from '../componentOptions'
-import { observable, computed } from '@vue/observer'
-import { setupWatcher } from '../componentWatch'
-
-type RawEffect = () => (() => void) | void
-
-type Effect = RawEffect & {
-  current?: RawEffect | null | void
-}
-
-type EffectRecord = {
-  effect: Effect
-  cleanup: Effect
-  deps: any[] | void
-}
-
-type Ref<T> = { current: T }
-
-type HookState = {
-  state: any
-  effects: Record<number, EffectRecord>
-  refs: Record<number, Ref<any>>
-}
-
-let currentInstance: ComponentInstance | null = null
-let isMounting: boolean = false
-let callIndex: number = 0
-
-const hooksStateMap = new WeakMap<ComponentInstance, HookState>()
-
-export function setCurrentInstance(instance: ComponentInstance) {
-  currentInstance = instance
-  isMounting = !currentInstance._mounted
-  callIndex = 0
-}
-
-export function unsetCurrentInstance() {
-  currentInstance = null
-}
-
-function ensureCurrentInstance() {
-  if (!currentInstance) {
-    throw new Error(
-      `invalid hooks call` +
-        (__DEV__
-          ? `. Hooks can only be called in one of the following: ` +
-            `render(), hooks(), or withHooks().`
-          : ``)
-    )
-  }
-}
-
-function getCurrentHookState(): HookState {
-  ensureCurrentInstance()
-  let hookState = hooksStateMap.get(currentInstance as ComponentInstance)
-  if (!hookState) {
-    hookState = {
-      state: observable({}),
-      effects: {},
-      refs: {}
-    }
-    hooksStateMap.set(currentInstance as ComponentInstance, hookState)
-  }
-  return hookState
-}
-
-// React compatible hooks ------------------------------------------------------
-
-export function useState<T>(initial: T): [T, (newValue: T) => void] {
-  const id = ++callIndex
-  const { state } = getCurrentHookState()
-  const set = (newValue: any) => {
-    state[id] = newValue
-  }
-  if (isMounting) {
-    set(initial)
-  }
-  return [state[id], set]
-}
-
-export function useEffect(rawEffect: Effect, deps?: any[]) {
-  const id = ++callIndex
-  if (isMounting) {
-    const cleanup: Effect = () => {
-      const { current } = cleanup
-      if (current) {
-        current()
-        cleanup.current = null
-      }
-    }
-    const effect: Effect = () => {
-      const { current } = effect
-      if (current) {
-        cleanup.current = current()
-        effect.current = null
-      }
-    }
-    effect.current = rawEffect
-    getCurrentHookState().effects[id] = {
-      effect,
-      cleanup,
-      deps
-    }
-
-    injectEffect(currentInstance as ComponentInstance, 'mounted', effect)
-    injectEffect(currentInstance as ComponentInstance, 'unmounted', cleanup)
-    if (!deps || deps.length !== 0) {
-      injectEffect(currentInstance as ComponentInstance, 'updated', effect)
-    }
-  } else {
-    const record = getCurrentHookState().effects[id]
-    const { effect, cleanup, deps: prevDeps = [] } = record
-    record.deps = deps
-    if (!deps || hasDepsChanged(deps, prevDeps)) {
-      cleanup()
-      effect.current = rawEffect
-    }
-  }
-}
-
-function hasDepsChanged(deps: any[], prevDeps: any[]): boolean {
-  if (deps.length !== prevDeps.length) {
-    return true
-  }
-  for (let i = 0; i < deps.length; i++) {
-    if (deps[i] !== prevDeps[i]) {
-      return true
-    }
-  }
-  return false
-}
-
-function injectEffect(
-  instance: ComponentInstance,
-  key: string,
-  effect: Effect
-) {
-  const existing = instance.$options[key]
-  ;(instance.$options as any)[key] = existing
-    ? mergeLifecycleHooks(existing, effect)
-    : effect
-}
-
-export function useRef<T>(initial?: T): Ref<T> {
-  const id = ++callIndex
-  const { refs } = getCurrentHookState()
-  return isMounting ? (refs[id] = { current: initial }) : refs[id]
-}
-
-// Vue API hooks ---------------------------------------------------------------
-
-export function useData<T>(initial: T): T {
-  const id = ++callIndex
-  const { state } = getCurrentHookState()
-  if (isMounting) {
-    state[id] = initial
-  }
-  return state[id]
-}
-
-export function useMounted(fn: () => void) {
-  useEffect(fn, [])
-}
-
-export function useUnmounted(fn: () => void) {
-  useEffect(() => fn, [])
-}
-
-export function useUpdated(fn: () => void, deps?: any[]) {
-  const isMount = useRef(true)
-  useEffect(() => {
-    if (isMount.current) {
-      isMount.current = false
-    } else {
-      return fn()
-    }
-  }, deps)
-}
-
-export function useWatch<T>(
-  getter: () => T,
-  cb: (val: T, oldVal: T) => void,
-  options?: WatchOptions
-) {
-  ensureCurrentInstance()
-  if (isMounting) {
-    setupWatcher(currentInstance as ComponentInstance, getter, cb, options)
-  }
-}
-
-export function useComputed<T>(getter: () => T): T {
-  ensureCurrentInstance()
-  const id = `__hooksComputed${++callIndex}`
-  const instance = currentInstance as ComponentInstance
-  const handles = instance._computedGetters || (instance._computedGetters = {})
-  if (isMounting) {
-    handles[id] = computed(getter)
-  }
-  return handles[id]()
-}
index 56f9a4877bdd0bd75ded43c5d3b89a96055f9433..078e319591a1386636bd725d5c813493b59b32c7 100644 (file)
@@ -32,19 +32,6 @@ export { mixins } from './optional/mixins'
 export { EventEmitter } from './optional/eventEmitter'
 export { memoize } from './optional/memoize'
 
-// Experimental APIs
-export {
-  useState,
-  useEffect,
-  useRef,
-  useData,
-  useWatch,
-  useComputed,
-  useMounted,
-  useUnmounted,
-  useUpdated
-} from './experimental/hooks'
-
 // flags & types
 export { ComponentType, ComponentClass, FunctionalComponent } from './component'
 export { VNodeFlags, ChildrenFlags } from './flags'