]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: vnodeXXX directive hooks
authorEvan You <yyx990803@gmail.com>
Sat, 31 Aug 2019 21:06:39 +0000 (17:06 -0400)
committerEvan You <yyx990803@gmail.com>
Sat, 31 Aug 2019 21:06:39 +0000 (17:06 -0400)
packages/runtime-core/src/createRenderer.ts
packages/runtime-core/src/directives.ts
packages/runtime-core/src/errorHandling.ts
packages/shared/src/index.ts

index 91221e5500dfba5d6a3b70feb4453b7160adfde1..7870299ad2b1ab9f9ab32672267b858dd9c0e52b 100644 (file)
@@ -35,6 +35,7 @@ import { resolveSlots } from './componentSlots'
 import { PatchFlags } from './patchFlags'
 import { ShapeFlags } from './shapeFlags'
 import { pushWarningContext, popWarningContext, warn } from './warning'
+import { invokeDirectiveHook } from './directives'
 
 const prodEffectOptions = {
   scheduler: queueJob
@@ -248,6 +249,7 @@ export function createRenderer(options: RendererOptions) {
         if (isReservedProp(key)) continue
         hostPatchProp(el, key, props[key], null, isSVG)
       }
+      invokeDirectiveHook(props.vnodeBeforeMount, parentComponent, vnode)
     }
     if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
       hostSetElementText(el, vnode.children as string)
@@ -261,6 +263,9 @@ export function createRenderer(options: RendererOptions) {
       )
     }
     hostInsert(el, container, anchor)
+    if (props != null) {
+      invokeDirectiveHook(props.vnodeMounted, parentComponent, vnode)
+    }
   }
 
   function mountChildren(
index 46a697e6241090d779357f6612ab9cb1430351f1..bb799aa82eeab02d785c6e3af5ce66fe6fe9a90c 100644 (file)
@@ -13,13 +13,14 @@ return applyDirectives(
 */
 
 import { VNode, cloneVNode } from './vnode'
-import { extend } from '@vue/shared'
+import { extend, isArray, isFunction } from '@vue/shared'
 import { warn } from './warning'
 import {
   ComponentInstance,
   currentRenderingInstance,
   ComponentRenderProxy
 } from './component'
+import { callWithAsyncErrorHandling, ErrorTypes } from './errorHandling'
 
 interface DirectiveBinding {
   instance: ComponentRenderProxy | null
@@ -120,3 +121,26 @@ export function resolveDirective(name: string): Directive {
   // TODO
   return {} as any
 }
+
+export function invokeDirectiveHook(
+  hook: Function | Function[],
+  instance: ComponentInstance | null,
+  vnode: VNode
+) {
+  if (hook == null) {
+    return
+  }
+  const args = [vnode]
+  if (isArray(hook)) {
+    for (let i = 0; i < hook.length; i++) {
+      callWithAsyncErrorHandling(
+        hook[i],
+        instance,
+        ErrorTypes.DIRECTIVE_HOOK,
+        args
+      )
+    }
+  } else if (isFunction(hook)) {
+    callWithAsyncErrorHandling(hook, instance, ErrorTypes.DIRECTIVE_HOOK, args)
+  }
+}
index 7cad6a352574c59f3ed7619b63b29f4dc2452917..0f02732d8d773fab1300fa83c33ec8f90dc9e22e 100644 (file)
@@ -12,6 +12,7 @@ export const enum ErrorTypes {
   WATCH_CLEANUP,
   NATIVE_EVENT_HANDLER,
   COMPONENT_EVENT_HANDLER,
+  DIRECTIVE_HOOK,
   SCHEDULER
 }
 
@@ -36,6 +37,7 @@ export const ErrorTypeStrings: Record<number | string, string> = {
   [ErrorTypes.WATCH_CLEANUP]: 'watcher cleanup function',
   [ErrorTypes.NATIVE_EVENT_HANDLER]: 'native event handler',
   [ErrorTypes.COMPONENT_EVENT_HANDLER]: 'component event handler',
+  [ErrorTypes.DIRECTIVE_HOOK]: 'directive hook',
   [ErrorTypes.SCHEDULER]:
     'scheduler flush. This may be a Vue internals bug. ' +
     'Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue'
index 9e857a64ef145326bff0a05e571b306ef8886174..469826aebd1243e7936f2a49a0d6dcbf3d2135f2 100644 (file)
@@ -3,8 +3,6 @@ export const EMPTY_ARR: [] = []
 
 export const NOOP = () => {}
 
-export const reservedPropRE = /^(?:key|ref|slots)$|^vnode/
-
 export const isOn = (key: string) => key[0] === 'o' && key[1] === 'n'
 
 export const extend = <T extends object, U extends object>(
@@ -24,8 +22,9 @@ export const isString = (val: any): val is string => typeof val === 'string'
 export const isObject = (val: any): val is Record<any, any> =>
   val !== null && typeof val === 'object'
 
+const vnodeHooksRE = /^vnode/
 export const isReservedProp = (key: string): boolean =>
-  key === 'key' || key === 'ref'
+  key === 'key' || key === 'ref' || vnodeHooksRE.test(key)
 
 const camelizeRE = /-(\w)/g
 export const camelize = (str: string): string => {