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 } =
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
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)) {
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 {
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) ||