refactor: tweak applyDirectives
This commit is contained in:
parent
1a68bcb4a7
commit
b527705928
@ -15,7 +15,7 @@ export { createComponentInstance } from './componentUtils'
|
||||
|
||||
// Optional APIs
|
||||
// these are imported on-demand and can be tree-shaken
|
||||
export { applyDirective } from './optional/directive'
|
||||
export { applyDirectives } from './optional/directive'
|
||||
export { Provide, Inject } from './optional/context'
|
||||
export { createAsyncComponent } from './optional/asyncComponent'
|
||||
export { KeepAlive } from './optional/keepAlive'
|
||||
|
@ -1,5 +1,21 @@
|
||||
import { VNode } from '../vdom'
|
||||
/**
|
||||
Runtime helper for applying directives to a vnode. Example usage:
|
||||
|
||||
const comp = resolveComponent(this, 'comp')
|
||||
const foo = resolveDirective(this, 'foo')
|
||||
const bar = resolveDirective(this, 'bar')
|
||||
|
||||
return applyDirectives(
|
||||
h(comp),
|
||||
this,
|
||||
[foo, this.x],
|
||||
[bar, this.y]
|
||||
)
|
||||
*/
|
||||
|
||||
import { VNode, cloneVNode, VNodeData } from '../vdom'
|
||||
import { ComponentInstance } from '../component'
|
||||
import { EMPTY_OBJ } from '../utils'
|
||||
|
||||
interface DirectiveBinding {
|
||||
instance: ComponentInstance
|
||||
@ -30,14 +46,13 @@ type DirectiveModifiers = Record<string, boolean>
|
||||
const valueCache = new WeakMap<Directive, WeakMap<any, any>>()
|
||||
|
||||
export function applyDirective(
|
||||
vnode: VNode,
|
||||
data: VNodeData,
|
||||
instance: ComponentInstance,
|
||||
directive: Directive,
|
||||
value?: any,
|
||||
arg?: string,
|
||||
modifiers?: DirectiveModifiers
|
||||
): VNode {
|
||||
const data = vnode.data || (vnode.data = {})
|
||||
) {
|
||||
let valueCacheForDir = valueCache.get(directive) as WeakMap<VNode, any>
|
||||
if (!valueCacheForDir) {
|
||||
valueCacheForDir = new WeakMap<VNode, any>()
|
||||
@ -67,9 +82,10 @@ export function applyDirective(
|
||||
)
|
||||
}
|
||||
const existing = data[hookKey]
|
||||
data[hookKey] = existing ? [].concat(existing, vnodeHook as any) : vnodeHook
|
||||
data[hookKey] = existing
|
||||
? [].concat(existing as any, vnodeHook as any)
|
||||
: vnodeHook
|
||||
}
|
||||
return vnode
|
||||
}
|
||||
|
||||
type DirectiveArguments = [
|
||||
@ -84,8 +100,9 @@ export function applyDirectives(
|
||||
instance: ComponentInstance,
|
||||
...directives: DirectiveArguments
|
||||
) {
|
||||
vnode = cloneVNode(vnode, EMPTY_OBJ)
|
||||
for (let i = 0; i < directives.length; i++) {
|
||||
applyDirective(vnode, instance, ...directives[i])
|
||||
applyDirective(vnode.data as VNodeData, instance, ...directives[i])
|
||||
}
|
||||
return vnode
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
} from './component'
|
||||
import { VNodeFlags, ChildrenFlags } from './flags'
|
||||
import { createComponentClassFromOptions } from './componentUtils'
|
||||
import { normalizeClass, normalizeStyle, handlersRE } from './utils'
|
||||
import { normalizeClass, normalizeStyle, handlersRE, EMPTY_OBJ } from './utils'
|
||||
|
||||
// Vue core is platform agnostic, so we are not using Element for "DOM" nodes.
|
||||
export interface RenderNode {
|
||||
@ -264,19 +264,27 @@ export function cloneVNode(vnode: VNode, extraData?: VNodeData): VNode {
|
||||
clonedData[key] = data[key]
|
||||
}
|
||||
}
|
||||
for (const key in extraData) {
|
||||
if (key === 'class') {
|
||||
clonedData.class = normalizeClass([clonedData.class, extraData.class])
|
||||
} else if (key === 'style') {
|
||||
clonedData.style = normalizeStyle([clonedData.style, extraData.style])
|
||||
} else if (handlersRE.test(key)) {
|
||||
// on*, nativeOn*, vnode*
|
||||
const existing = clonedData[key]
|
||||
clonedData[key] = existing
|
||||
? [].concat(existing, extraData[key])
|
||||
: extraData[key]
|
||||
} else {
|
||||
clonedData[key] = extraData[key]
|
||||
if (extraData !== EMPTY_OBJ) {
|
||||
for (const key in extraData) {
|
||||
if (key === 'class') {
|
||||
clonedData.class = normalizeClass([
|
||||
clonedData.class,
|
||||
extraData.class
|
||||
])
|
||||
} else if (key === 'style') {
|
||||
clonedData.style = normalizeStyle([
|
||||
clonedData.style,
|
||||
extraData.style
|
||||
])
|
||||
} else if (handlersRE.test(key)) {
|
||||
// on*, nativeOn*, vnode*
|
||||
const existing = clonedData[key]
|
||||
clonedData[key] = existing
|
||||
? [].concat(existing, extraData[key])
|
||||
: extraData[key]
|
||||
} else {
|
||||
clonedData[key] = extraData[key]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user