vue3-yuanma/packages/runtime-core/src/compat/componentFunctional.ts
2021-04-29 15:51:37 -04:00

64 lines
1.7 KiB
TypeScript

import {
ComponentOptions,
FunctionalComponent,
getCurrentInstance
} from '../component'
import { resolveInjections } from '../componentOptions'
import { InternalSlots } from '../componentSlots'
import { getCompatListeners } from './instanceListeners'
import { compatH } from './renderFn'
const normalizedFunctionalComponentMap = new Map<
ComponentOptions,
FunctionalComponent
>()
export const legacySlotProxyHandlers: ProxyHandler<InternalSlots> = {
get(target, key: string) {
const slot = target[key]
return slot && slot()
}
}
export function convertLegacyFunctionalComponent(comp: ComponentOptions) {
if (normalizedFunctionalComponentMap.has(comp)) {
return normalizedFunctionalComponentMap.get(comp)!
}
const legacyFn = comp.render as any
const Func: FunctionalComponent = (props, ctx) => {
const instance = getCurrentInstance()!
const legacyCtx = {
props,
children: instance.vnode.children || [],
data: instance.vnode.props || {},
scopedSlots: ctx.slots,
parent: instance.parent && instance.parent.proxy,
slots() {
return new Proxy(ctx.slots, legacySlotProxyHandlers)
},
get listeners() {
return getCompatListeners(instance)
},
get injections() {
if (comp.inject) {
const injections = {}
resolveInjections(comp.inject, injections)
return injections
}
return {}
}
}
return legacyFn(compatH, legacyCtx)
}
Func.props = comp.props
Func.displayName = comp.name
// v2 functional components do not inherit attrs
Func.inheritAttrs = false
normalizedFunctionalComponentMap.set(comp, Func)
return Func
}