|
|
@@ -270,6 +270,9 @@ export interface ComponentRenderContext {
|
|
|
|
|
|
export const isReservedPrefix = (key: string) => key === '_' || key === '$'
|
|
|
|
|
|
+const hasSetupBinding = (state: Data, key: string) =>
|
|
|
+ state !== EMPTY_OBJ && !state.__isScriptSetup && hasOwn(state, key)
|
|
|
+
|
|
|
export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
|
|
|
get({ _: instance }: ComponentRenderContext, key: string) {
|
|
|
const { ctx, setupState, data, props, accessCache, type, appContext } =
|
|
|
@@ -280,19 +283,6 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
|
|
|
return true
|
|
|
}
|
|
|
|
|
|
- // prioritize <script setup> bindings during dev.
|
|
|
- // this allows even properties that start with _ or $ to be used - so that
|
|
|
- // it aligns with the production behavior where the render fn is inlined and
|
|
|
- // indeed has access to all declared variables.
|
|
|
- if (
|
|
|
- __DEV__ &&
|
|
|
- setupState !== EMPTY_OBJ &&
|
|
|
- setupState.__isScriptSetup &&
|
|
|
- hasOwn(setupState, key)
|
|
|
- ) {
|
|
|
- return setupState[key]
|
|
|
- }
|
|
|
-
|
|
|
// data / props / ctx
|
|
|
// This getter gets called for every property access on the render context
|
|
|
// during render and is a major hotspot. The most expensive part of this
|
|
|
@@ -314,7 +304,7 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
|
|
|
return props![key]
|
|
|
// default: just fallthrough
|
|
|
}
|
|
|
- } else if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
|
|
|
+ } else if (hasSetupBinding(setupState, key)) {
|
|
|
accessCache![key] = AccessTypes.SETUP
|
|
|
return setupState[key]
|
|
|
} else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
|
|
|
@@ -403,26 +393,28 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
|
|
|
value: any
|
|
|
): boolean {
|
|
|
const { data, setupState, ctx } = instance
|
|
|
- if (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) {
|
|
|
+ if (hasSetupBinding(setupState, key)) {
|
|
|
setupState[key] = value
|
|
|
return true
|
|
|
+ } else if (
|
|
|
+ __DEV__ &&
|
|
|
+ setupState.__isScriptSetup &&
|
|
|
+ hasOwn(setupState, key)
|
|
|
+ ) {
|
|
|
+ warn(`Cannot mutate <script setup> binding "${key}" from Options API.`)
|
|
|
+ return false
|
|
|
} else if (data !== EMPTY_OBJ && hasOwn(data, key)) {
|
|
|
data[key] = value
|
|
|
return true
|
|
|
} else if (hasOwn(instance.props, key)) {
|
|
|
- __DEV__ &&
|
|
|
- warn(
|
|
|
- `Attempting to mutate prop "${key}". Props are readonly.`,
|
|
|
- instance
|
|
|
- )
|
|
|
+ __DEV__ && warn(`Attempting to mutate prop "${key}". Props are readonly.`)
|
|
|
return false
|
|
|
}
|
|
|
if (key[0] === '$' && key.slice(1) in instance) {
|
|
|
__DEV__ &&
|
|
|
warn(
|
|
|
`Attempting to mutate public property "${key}". ` +
|
|
|
- `Properties starting with $ are reserved and readonly.`,
|
|
|
- instance
|
|
|
+ `Properties starting with $ are reserved and readonly.`
|
|
|
)
|
|
|
return false
|
|
|
} else {
|
|
|
@@ -449,7 +441,7 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
|
|
|
return (
|
|
|
!!accessCache![key] ||
|
|
|
(data !== EMPTY_OBJ && hasOwn(data, key)) ||
|
|
|
- (setupState !== EMPTY_OBJ && hasOwn(setupState, key)) ||
|
|
|
+ hasSetupBinding(setupState, key) ||
|
|
|
((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
|
|
|
hasOwn(ctx, key) ||
|
|
|
hasOwn(publicPropertiesMap, key) ||
|