mirror of https://github.com/vuejs/core.git
wip: get instance from rawProps to fix proxy handler caching
This commit is contained in:
parent
f6f3f14a3e
commit
238d1817cc
|
@ -32,6 +32,11 @@ import { renderEffect } from './renderEffect'
|
|||
import { emit, normalizeEmitsOptions } from './componentEmits'
|
||||
import { setStyle } from './dom/style'
|
||||
import { setClass, setDynamicProp } from './dom/prop'
|
||||
import {
|
||||
type RawSlots,
|
||||
type Slot,
|
||||
getSlotsProxyHandlers,
|
||||
} from './componentSlots'
|
||||
|
||||
export { currentInstance } from '@vue/runtime-dom'
|
||||
|
||||
|
@ -170,9 +175,10 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
|||
|
||||
block: Block
|
||||
scope: EffectScope
|
||||
rawProps: RawProps | undefined
|
||||
rawProps: RawProps
|
||||
props: Record<string, any>
|
||||
attrs: Record<string, any>
|
||||
slots: Record<string, Slot>
|
||||
exposed: Record<string, any> | null
|
||||
|
||||
emitted: Record<string, boolean> | null
|
||||
|
@ -215,7 +221,7 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
|||
propsOptions?: NormalizedPropsOptions
|
||||
emitsOptions?: ObjectEmitsOptions | null
|
||||
|
||||
constructor(comp: VaporComponent, rawProps?: RawProps) {
|
||||
constructor(comp: VaporComponent, rawProps?: RawProps, rawSlots?: RawSlots) {
|
||||
this.vapor = true
|
||||
this.uid = nextUid()
|
||||
this.type = comp
|
||||
|
@ -240,12 +246,20 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
|||
false
|
||||
|
||||
// init props
|
||||
const target = rawProps || EMPTY_OBJ
|
||||
const handlers = getPropsProxyHandlers(comp, this)
|
||||
this.rawProps = rawProps
|
||||
this.props = comp.props ? new Proxy(target, handlers[0]!) : {}
|
||||
this.attrs = new Proxy(target, handlers[1])
|
||||
this.rawProps = rawProps || EMPTY_OBJ
|
||||
this.hasFallthrough = hasFallthroughAttrs(comp, rawProps)
|
||||
if (rawProps || comp.props) {
|
||||
const [propsHandlers, attrsHandlers] = getPropsProxyHandlers(comp)
|
||||
this.props = comp.props ? new Proxy(this, propsHandlers!) : {}
|
||||
this.attrs = new Proxy(this, attrsHandlers)
|
||||
} else {
|
||||
this.props = this.attrs = EMPTY_OBJ
|
||||
}
|
||||
|
||||
// init slots
|
||||
this.slots = rawSlots
|
||||
? new Proxy(rawSlots, getSlotsProxyHandlers(comp))
|
||||
: EMPTY_OBJ
|
||||
|
||||
if (__DEV__) {
|
||||
// validate props
|
||||
|
@ -281,6 +295,11 @@ export class SetupContext<E = EmitsOptions> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used when a component cannot be resolved at compile time
|
||||
* and needs rely on runtime resolution - where it might fallback to a plain
|
||||
* element if the resolution fails.
|
||||
*/
|
||||
export function createComponentWithFallback(
|
||||
comp: VaporComponent | string,
|
||||
rawProps: RawProps | undefined,
|
||||
|
|
|
@ -13,6 +13,7 @@ import { normalizeEmitsOptions } from './componentEmits'
|
|||
import { renderEffect } from './renderEffect'
|
||||
|
||||
export type RawProps = Record<string, () => unknown> & {
|
||||
// generated by compiler for :[key]="x" or v-bind="x"
|
||||
$?: DynamicPropsSource[]
|
||||
}
|
||||
|
||||
|
@ -27,12 +28,12 @@ export function resolveSource(
|
|||
return isFunction(source) ? source() : source
|
||||
}
|
||||
|
||||
const passThrough = (val: any) => val
|
||||
|
||||
export function getPropsProxyHandlers(
|
||||
comp: VaporComponent,
|
||||
instance: VaporComponentInstance,
|
||||
): [ProxyHandler<RawProps> | null, ProxyHandler<RawProps>] {
|
||||
): [
|
||||
ProxyHandler<VaporComponentInstance> | null,
|
||||
ProxyHandler<VaporComponentInstance>,
|
||||
] {
|
||||
if (comp.__propsHandlers) {
|
||||
return comp.__propsHandlers
|
||||
}
|
||||
|
@ -44,23 +45,12 @@ export function getPropsProxyHandlers(
|
|||
key !== '$' && !isProp(key) && !isEmitListener(emitsOptions, key)
|
||||
: YES
|
||||
|
||||
const castProp = propsOptions
|
||||
? (value: any, key: string, isAbsent = false) =>
|
||||
resolvePropValue(
|
||||
propsOptions,
|
||||
key as string,
|
||||
value,
|
||||
instance,
|
||||
resolveDefault,
|
||||
isAbsent,
|
||||
)
|
||||
: passThrough
|
||||
|
||||
const getProp = (target: RawProps, key: string) => {
|
||||
const getProp = (instance: VaporComponentInstance, key: string) => {
|
||||
if (key === '$' || !isProp(key)) {
|
||||
return
|
||||
}
|
||||
const dynamicSources = target.$
|
||||
const rawProps = instance.rawProps
|
||||
const dynamicSources = rawProps.$
|
||||
if (dynamicSources) {
|
||||
let i = dynamicSources.length
|
||||
let source, isDynamic, rawKey
|
||||
|
@ -70,17 +60,35 @@ export function getPropsProxyHandlers(
|
|||
source = isDynamic ? (source as Function)() : source
|
||||
for (rawKey in source) {
|
||||
if (camelize(rawKey) === key) {
|
||||
return castProp(isDynamic ? source[rawKey] : source[rawKey](), key)
|
||||
return resolvePropValue(
|
||||
propsOptions!,
|
||||
key,
|
||||
isDynamic ? source[rawKey] : source[rawKey](),
|
||||
instance,
|
||||
resolveDefault,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const rawKey in target) {
|
||||
for (const rawKey in rawProps) {
|
||||
if (camelize(rawKey) === key) {
|
||||
return castProp(target[rawKey](), key)
|
||||
return resolvePropValue(
|
||||
propsOptions!,
|
||||
key,
|
||||
rawProps[rawKey](),
|
||||
instance,
|
||||
resolveDefault,
|
||||
)
|
||||
}
|
||||
}
|
||||
return castProp(undefined, key, true)
|
||||
return resolvePropValue(
|
||||
propsOptions!,
|
||||
key,
|
||||
undefined,
|
||||
instance,
|
||||
resolveDefault,
|
||||
)
|
||||
}
|
||||
|
||||
const propsHandlers = propsOptions
|
||||
|
@ -99,7 +107,7 @@ export function getPropsProxyHandlers(
|
|||
ownKeys: () => Object.keys(propsOptions),
|
||||
set: NO,
|
||||
deleteProperty: NO,
|
||||
} satisfies ProxyHandler<RawProps>)
|
||||
} satisfies ProxyHandler<VaporComponentInstance>)
|
||||
: null
|
||||
|
||||
const getAttr = (target: RawProps, key: string) => {
|
||||
|
@ -142,25 +150,24 @@ export function getPropsProxyHandlers(
|
|||
}
|
||||
|
||||
const attrsHandlers = {
|
||||
get: (target, key: string) => {
|
||||
return getAttr(target, key)
|
||||
},
|
||||
has: hasAttr,
|
||||
get: (target, key: string) => getAttr(target.rawProps, key),
|
||||
has: (target, key: string) => hasAttr(target.rawProps, key),
|
||||
getOwnPropertyDescriptor(target, key: string) {
|
||||
if (hasAttr(target, key)) {
|
||||
if (hasAttr(target.rawProps, key)) {
|
||||
return {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: () => getAttr(target, key),
|
||||
get: () => getAttr(target.rawProps, key),
|
||||
}
|
||||
}
|
||||
},
|
||||
ownKeys(target) {
|
||||
const rawProps = target.rawProps
|
||||
const keys: string[] = []
|
||||
for (const key in target) {
|
||||
for (const key in rawProps) {
|
||||
if (isAttr(key)) keys.push(key)
|
||||
}
|
||||
const dynamicSources = target.$
|
||||
const dynamicSources = rawProps.$
|
||||
if (dynamicSources) {
|
||||
let i = dynamicSources.length
|
||||
let source
|
||||
|
@ -175,7 +182,7 @@ export function getPropsProxyHandlers(
|
|||
},
|
||||
set: NO,
|
||||
deleteProperty: NO,
|
||||
} satisfies ProxyHandler<RawProps>
|
||||
} satisfies ProxyHandler<VaporComponentInstance>
|
||||
|
||||
return (comp.__propsHandlers = [propsHandlers, attrsHandlers])
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue