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 { emit, normalizeEmitsOptions } from './componentEmits'
|
||||||
import { setStyle } from './dom/style'
|
import { setStyle } from './dom/style'
|
||||||
import { setClass, setDynamicProp } from './dom/prop'
|
import { setClass, setDynamicProp } from './dom/prop'
|
||||||
|
import {
|
||||||
|
type RawSlots,
|
||||||
|
type Slot,
|
||||||
|
getSlotsProxyHandlers,
|
||||||
|
} from './componentSlots'
|
||||||
|
|
||||||
export { currentInstance } from '@vue/runtime-dom'
|
export { currentInstance } from '@vue/runtime-dom'
|
||||||
|
|
||||||
|
@ -170,9 +175,10 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
||||||
|
|
||||||
block: Block
|
block: Block
|
||||||
scope: EffectScope
|
scope: EffectScope
|
||||||
rawProps: RawProps | undefined
|
rawProps: RawProps
|
||||||
props: Record<string, any>
|
props: Record<string, any>
|
||||||
attrs: Record<string, any>
|
attrs: Record<string, any>
|
||||||
|
slots: Record<string, Slot>
|
||||||
exposed: Record<string, any> | null
|
exposed: Record<string, any> | null
|
||||||
|
|
||||||
emitted: Record<string, boolean> | null
|
emitted: Record<string, boolean> | null
|
||||||
|
@ -215,7 +221,7 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
||||||
propsOptions?: NormalizedPropsOptions
|
propsOptions?: NormalizedPropsOptions
|
||||||
emitsOptions?: ObjectEmitsOptions | null
|
emitsOptions?: ObjectEmitsOptions | null
|
||||||
|
|
||||||
constructor(comp: VaporComponent, rawProps?: RawProps) {
|
constructor(comp: VaporComponent, rawProps?: RawProps, rawSlots?: RawSlots) {
|
||||||
this.vapor = true
|
this.vapor = true
|
||||||
this.uid = nextUid()
|
this.uid = nextUid()
|
||||||
this.type = comp
|
this.type = comp
|
||||||
|
@ -240,12 +246,20 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
||||||
false
|
false
|
||||||
|
|
||||||
// init props
|
// init props
|
||||||
const target = rawProps || EMPTY_OBJ
|
this.rawProps = 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.hasFallthrough = hasFallthroughAttrs(comp, rawProps)
|
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__) {
|
if (__DEV__) {
|
||||||
// validate props
|
// 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(
|
export function createComponentWithFallback(
|
||||||
comp: VaporComponent | string,
|
comp: VaporComponent | string,
|
||||||
rawProps: RawProps | undefined,
|
rawProps: RawProps | undefined,
|
||||||
|
|
|
@ -13,6 +13,7 @@ import { normalizeEmitsOptions } from './componentEmits'
|
||||||
import { renderEffect } from './renderEffect'
|
import { renderEffect } from './renderEffect'
|
||||||
|
|
||||||
export type RawProps = Record<string, () => unknown> & {
|
export type RawProps = Record<string, () => unknown> & {
|
||||||
|
// generated by compiler for :[key]="x" or v-bind="x"
|
||||||
$?: DynamicPropsSource[]
|
$?: DynamicPropsSource[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,12 +28,12 @@ export function resolveSource(
|
||||||
return isFunction(source) ? source() : source
|
return isFunction(source) ? source() : source
|
||||||
}
|
}
|
||||||
|
|
||||||
const passThrough = (val: any) => val
|
|
||||||
|
|
||||||
export function getPropsProxyHandlers(
|
export function getPropsProxyHandlers(
|
||||||
comp: VaporComponent,
|
comp: VaporComponent,
|
||||||
instance: VaporComponentInstance,
|
): [
|
||||||
): [ProxyHandler<RawProps> | null, ProxyHandler<RawProps>] {
|
ProxyHandler<VaporComponentInstance> | null,
|
||||||
|
ProxyHandler<VaporComponentInstance>,
|
||||||
|
] {
|
||||||
if (comp.__propsHandlers) {
|
if (comp.__propsHandlers) {
|
||||||
return comp.__propsHandlers
|
return comp.__propsHandlers
|
||||||
}
|
}
|
||||||
|
@ -44,23 +45,12 @@ export function getPropsProxyHandlers(
|
||||||
key !== '$' && !isProp(key) && !isEmitListener(emitsOptions, key)
|
key !== '$' && !isProp(key) && !isEmitListener(emitsOptions, key)
|
||||||
: YES
|
: YES
|
||||||
|
|
||||||
const castProp = propsOptions
|
const getProp = (instance: VaporComponentInstance, key: string) => {
|
||||||
? (value: any, key: string, isAbsent = false) =>
|
|
||||||
resolvePropValue(
|
|
||||||
propsOptions,
|
|
||||||
key as string,
|
|
||||||
value,
|
|
||||||
instance,
|
|
||||||
resolveDefault,
|
|
||||||
isAbsent,
|
|
||||||
)
|
|
||||||
: passThrough
|
|
||||||
|
|
||||||
const getProp = (target: RawProps, key: string) => {
|
|
||||||
if (key === '$' || !isProp(key)) {
|
if (key === '$' || !isProp(key)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const dynamicSources = target.$
|
const rawProps = instance.rawProps
|
||||||
|
const dynamicSources = rawProps.$
|
||||||
if (dynamicSources) {
|
if (dynamicSources) {
|
||||||
let i = dynamicSources.length
|
let i = dynamicSources.length
|
||||||
let source, isDynamic, rawKey
|
let source, isDynamic, rawKey
|
||||||
|
@ -70,17 +60,35 @@ export function getPropsProxyHandlers(
|
||||||
source = isDynamic ? (source as Function)() : source
|
source = isDynamic ? (source as Function)() : source
|
||||||
for (rawKey in source) {
|
for (rawKey in source) {
|
||||||
if (camelize(rawKey) === key) {
|
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) {
|
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
|
const propsHandlers = propsOptions
|
||||||
|
@ -99,7 +107,7 @@ export function getPropsProxyHandlers(
|
||||||
ownKeys: () => Object.keys(propsOptions),
|
ownKeys: () => Object.keys(propsOptions),
|
||||||
set: NO,
|
set: NO,
|
||||||
deleteProperty: NO,
|
deleteProperty: NO,
|
||||||
} satisfies ProxyHandler<RawProps>)
|
} satisfies ProxyHandler<VaporComponentInstance>)
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const getAttr = (target: RawProps, key: string) => {
|
const getAttr = (target: RawProps, key: string) => {
|
||||||
|
@ -142,25 +150,24 @@ export function getPropsProxyHandlers(
|
||||||
}
|
}
|
||||||
|
|
||||||
const attrsHandlers = {
|
const attrsHandlers = {
|
||||||
get: (target, key: string) => {
|
get: (target, key: string) => getAttr(target.rawProps, key),
|
||||||
return getAttr(target, key)
|
has: (target, key: string) => hasAttr(target.rawProps, key),
|
||||||
},
|
|
||||||
has: hasAttr,
|
|
||||||
getOwnPropertyDescriptor(target, key: string) {
|
getOwnPropertyDescriptor(target, key: string) {
|
||||||
if (hasAttr(target, key)) {
|
if (hasAttr(target.rawProps, key)) {
|
||||||
return {
|
return {
|
||||||
configurable: true,
|
configurable: true,
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
get: () => getAttr(target, key),
|
get: () => getAttr(target.rawProps, key),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ownKeys(target) {
|
ownKeys(target) {
|
||||||
|
const rawProps = target.rawProps
|
||||||
const keys: string[] = []
|
const keys: string[] = []
|
||||||
for (const key in target) {
|
for (const key in rawProps) {
|
||||||
if (isAttr(key)) keys.push(key)
|
if (isAttr(key)) keys.push(key)
|
||||||
}
|
}
|
||||||
const dynamicSources = target.$
|
const dynamicSources = rawProps.$
|
||||||
if (dynamicSources) {
|
if (dynamicSources) {
|
||||||
let i = dynamicSources.length
|
let i = dynamicSources.length
|
||||||
let source
|
let source
|
||||||
|
@ -175,7 +182,7 @@ export function getPropsProxyHandlers(
|
||||||
},
|
},
|
||||||
set: NO,
|
set: NO,
|
||||||
deleteProperty: NO,
|
deleteProperty: NO,
|
||||||
} satisfies ProxyHandler<RawProps>
|
} satisfies ProxyHandler<VaporComponentInstance>
|
||||||
|
|
||||||
return (comp.__propsHandlers = [propsHandlers, attrsHandlers])
|
return (comp.__propsHandlers = [propsHandlers, attrsHandlers])
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue