mirror of https://github.com/vuejs/core.git
wip: slots proxy
This commit is contained in:
parent
685f7820a1
commit
3ef1656d4a
|
@ -34,8 +34,8 @@ import { setStyle } from './dom/style'
|
||||||
import { setClass, setDynamicProp } from './dom/prop'
|
import { setClass, setDynamicProp } from './dom/prop'
|
||||||
import {
|
import {
|
||||||
type RawSlots,
|
type RawSlots,
|
||||||
type Slot,
|
type StaticSlots,
|
||||||
getSlotsProxyHandlers,
|
slotsProxyHandlers,
|
||||||
} from './componentSlots'
|
} from './componentSlots'
|
||||||
|
|
||||||
export { currentInstance } from '@vue/runtime-dom'
|
export { currentInstance } from '@vue/runtime-dom'
|
||||||
|
@ -178,7 +178,7 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
||||||
rawProps: RawProps
|
rawProps: RawProps
|
||||||
props: Record<string, any>
|
props: Record<string, any>
|
||||||
attrs: Record<string, any>
|
attrs: Record<string, any>
|
||||||
slots: Record<string, Slot>
|
slots: StaticSlots
|
||||||
exposed: Record<string, any> | null
|
exposed: Record<string, any> | null
|
||||||
|
|
||||||
emitted: Record<string, boolean> | null
|
emitted: Record<string, boolean> | null
|
||||||
|
@ -257,9 +257,7 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
||||||
}
|
}
|
||||||
|
|
||||||
// init slots
|
// init slots
|
||||||
this.slots = rawSlots
|
this.slots = rawSlots ? new Proxy(rawSlots, slotsProxyHandlers) : EMPTY_OBJ
|
||||||
? new Proxy(rawSlots, getSlotsProxyHandlers(comp))
|
|
||||||
: EMPTY_OBJ
|
|
||||||
|
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
// validate props
|
// validate props
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
import { NO, hasOwn, isArray, isFunction } from '@vue/shared'
|
||||||
|
import type { Block } from './block'
|
||||||
|
|
||||||
|
export type RawSlots = Record<string, Slot> & {
|
||||||
|
$?: (StaticSlots | DynamicSlotFn)[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export type StaticSlots = Record<string, Slot>
|
||||||
|
|
||||||
|
export type Slot = (...args: any[]) => Block
|
||||||
|
export type DynamicSlot = { name: string; fn: Slot }
|
||||||
|
export type DynamicSlotFn = () => DynamicSlot | DynamicSlot[]
|
||||||
|
|
||||||
|
export const slotsProxyHandlers: ProxyHandler<RawSlots> = {
|
||||||
|
get: getSlot,
|
||||||
|
has: (target, key: string) => !!getSlot(target, key),
|
||||||
|
getOwnPropertyDescriptor(target, key: string) {
|
||||||
|
const slot = getSlot(target, key)
|
||||||
|
if (slot) {
|
||||||
|
return {
|
||||||
|
configurable: true,
|
||||||
|
enumerable: true,
|
||||||
|
value: slot,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ownKeys(target) {
|
||||||
|
const keys = Object.keys(target)
|
||||||
|
const dynamicSources = target.$
|
||||||
|
if (dynamicSources) {
|
||||||
|
for (const source of dynamicSources) {
|
||||||
|
if (isFunction(source)) {
|
||||||
|
const slot = source()
|
||||||
|
if (isArray(slot)) {
|
||||||
|
for (const s of slot) keys.push(s.name)
|
||||||
|
} else {
|
||||||
|
keys.push(slot.name)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
keys.push(...Object.keys(source))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
},
|
||||||
|
set: NO,
|
||||||
|
deleteProperty: NO,
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSlot(target: RawSlots, key: string) {
|
||||||
|
const dynamicSources = target.$
|
||||||
|
if (dynamicSources) {
|
||||||
|
let i = dynamicSources.length
|
||||||
|
let source
|
||||||
|
while (i--) {
|
||||||
|
source = dynamicSources[i]
|
||||||
|
if (isFunction(source)) {
|
||||||
|
const slot = source()
|
||||||
|
if (isArray(slot)) {
|
||||||
|
for (const s of slot) {
|
||||||
|
if (s.name === key) return s.fn
|
||||||
|
}
|
||||||
|
} else if (slot.name === key) {
|
||||||
|
return slot.fn
|
||||||
|
}
|
||||||
|
} else if (hasOwn(source, key)) {
|
||||||
|
return source[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasOwn(target, key)) {
|
||||||
|
return target[key]
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue