From 1e447d021bc09aacde3eb0928d5721f83e1f03c6 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 25 Sep 2018 14:56:31 -0400 Subject: [PATCH] feat: applyDirective --- packages/core/src/component.ts | 4 +- packages/core/src/createRenderer.ts | 8 ++-- packages/core/src/directive.ts | 58 +++++++++++++++++++++++++++++ packages/core/src/index.ts | 1 + 4 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 packages/core/src/directive.ts diff --git a/packages/core/src/component.ts b/packages/core/src/component.ts index 34ef7e51..cf5d7c5c 100644 --- a/packages/core/src/component.ts +++ b/packages/core/src/component.ts @@ -48,8 +48,8 @@ export interface MountedComponent extends Component { mounted?(): void beforeUpdate?(vnode: VNode): void updated?(vnode: VNode): void - beforeDestroy?(): void - destroyed?(): void + beforeUnmount?(): void + unmounted?(): void errorCaptured?(): (err: Error, type: ErrorTypes) => boolean | void _updateHandle: Autorun diff --git a/packages/core/src/createRenderer.ts b/packages/core/src/createRenderer.ts index b6ff8dfd..7ddd730d 100644 --- a/packages/core/src/createRenderer.ts +++ b/packages/core/src/createRenderer.ts @@ -1270,8 +1270,8 @@ export function createRenderer(options: RendererOptions) { } function unmountComponentInstance(instance: MountedComponent) { - if (instance.beforeDestroy) { - instance.beforeDestroy.call(instance.$proxy) + if (instance.beforeUnmount) { + instance.beforeUnmount.call(instance.$proxy) } if (instance.$vnode) { unmount(instance.$vnode) @@ -1279,8 +1279,8 @@ export function createRenderer(options: RendererOptions) { stop(instance._updateHandle) teardownComponentInstance(instance) instance._destroyed = true - if (instance.destroyed) { - instance.destroyed.call(instance.$proxy) + if (instance.unmounted) { + instance.unmounted.call(instance.$proxy) } } diff --git a/packages/core/src/directive.ts b/packages/core/src/directive.ts new file mode 100644 index 00000000..5c0cdce6 --- /dev/null +++ b/packages/core/src/directive.ts @@ -0,0 +1,58 @@ +import { VNode } from './vdom' +import { MountedComponent } from './component' + +export interface DirectiveBinding { + instance: MountedComponent + value?: any + arg?: string + modifiers?: DirectiveModifiers +} + +export type DirectiveHook = ( + el: any, + binding: DirectiveBinding, + vnode: VNode, + prevVNode: VNode | void +) => void + +export interface Directive { + beforeMount: DirectiveHook + mounted: DirectiveHook + beforeUpdate: DirectiveHook + updated: DirectiveHook + beforeUnmount: DirectiveHook + unmounted: DirectiveHook +} + +type DirectiveModifiers = Record + +export function applyDirective( + vnode: VNode, + directive: Directive, + instance: MountedComponent, + value?: any, + arg?: string, + modifiers?: DirectiveModifiers +): VNode { + const data = vnode.data || (vnode.data = {}) + for (const key in directive) { + const hook = directive[key as keyof Directive] + const hookKey = `vnode` + key[0].toUpperCase() + key.slice(1) + const vnodeHook = (vnode: VNode, prevVNode?: VNode) => { + hook( + vnode.el, + { + instance, + value, + arg, + modifiers + }, + vnode, + prevVNode + ) + } + const existing = data[hookKey] + data[hookKey] = existing ? [].concat(existing, vnodeHook as any) : vnodeHook + } + return vnode +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index e838d806..d2312b93 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -15,6 +15,7 @@ export { nextTick } from '@vue/scheduler' // internal api export { createComponentInstance } from './componentUtils' +export { applyDirective } from './directive' // flags & types export { ComponentClass, FunctionalComponent } from './component'