feat: applyDirective

This commit is contained in:
Evan You 2018-09-25 14:56:31 -04:00
parent 7b7ae57388
commit 1e447d021b
4 changed files with 65 additions and 6 deletions

View File

@ -48,8 +48,8 @@ export interface MountedComponent<D = Data, P = Data> 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

View File

@ -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)
}
}

View File

@ -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<string, boolean>
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
}

View File

@ -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'