Skip to content

Commit d7283f3

Browse files
fix(runtime-core): improve consistency of PublicInstanceProxyHandlers.has (#13507)
1 parent 3190b17 commit d7283f3

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

packages/runtime-core/__tests__/componentPublicInstance.spec.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,33 +167,55 @@ describe('component: proxy', () => {
167167
data() {
168168
return {
169169
foo: 0,
170+
$foo: 0,
170171
}
171172
},
173+
computed: {
174+
cmp: () => {
175+
throw new Error('value of cmp should not be accessed')
176+
},
177+
$cmp: () => {
178+
throw new Error('value of $cmp should not be read')
179+
},
180+
},
172181
setup() {
173182
return {
174183
bar: 1,
175184
}
176185
},
186+
__cssModules: {
187+
$style: {},
188+
cssStyles: {},
189+
},
177190
mounted() {
178191
instanceProxy = this
179192
},
180193
}
181194

182195
const app = createApp(Comp, { msg: 'hello' })
183196
app.config.globalProperties.global = 1
197+
app.config.globalProperties.$global = 1
184198

185199
app.mount(nodeOps.createElement('div'))
186200

187201
// props
188202
expect('msg' in instanceProxy).toBe(true)
189203
// data
190204
expect('foo' in instanceProxy).toBe(true)
191-
// ctx
205+
expect('$foo' in instanceProxy).toBe(false)
206+
// setupState
192207
expect('bar' in instanceProxy).toBe(true)
208+
// ctx
209+
expect('cmp' in instanceProxy).toBe(true)
210+
expect('$cmp' in instanceProxy).toBe(true)
193211
// public properties
194212
expect('$el' in instanceProxy).toBe(true)
213+
// CSS modules
214+
expect('$style' in instanceProxy).toBe(true)
215+
expect('cssStyles' in instanceProxy).toBe(true)
195216
// global properties
196217
expect('global' in instanceProxy).toBe(true)
218+
expect('$global' in instanceProxy).toBe(true)
197219

198220
// non-existent
199221
expect('$foobar' in instanceProxy).toBe(false)
@@ -202,19 +224,26 @@ describe('component: proxy', () => {
202224
// #4962 triggering getter should not cause non-existent property to
203225
// pass the has check
204226
instanceProxy.baz
227+
instanceProxy.$baz
205228
expect('baz' in instanceProxy).toBe(false)
229+
expect('$baz' in instanceProxy).toBe(false)
206230

207231
// set non-existent (goes into proxyTarget sink)
208232
instanceProxy.baz = 1
209233
expect('baz' in instanceProxy).toBe(true)
234+
instanceProxy.$baz = 1
235+
expect('$baz' in instanceProxy).toBe(true)
210236

211237
// dev mode ownKeys check for console inspection
212238
// should only expose own keys
213239
expect(Object.keys(instanceProxy)).toMatchObject([
214240
'msg',
215241
'bar',
216242
'foo',
243+
'cmp',
244+
'$cmp',
217245
'baz',
246+
'$baz',
218247
])
219248
})
220249

packages/runtime-core/src/componentPublicInstance.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -575,19 +575,20 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
575575

576576
has(
577577
{
578-
_: { data, setupState, accessCache, ctx, appContext, propsOptions },
578+
_: { data, setupState, accessCache, ctx, appContext, propsOptions, type },
579579
}: ComponentRenderContext,
580580
key: string,
581581
) {
582-
let normalizedProps
583-
return (
584-
!!accessCache![key] ||
585-
(data !== EMPTY_OBJ && hasOwn(data, key)) ||
582+
let normalizedProps, cssModules
583+
return !!(
584+
accessCache![key] ||
585+
(data !== EMPTY_OBJ && key[0] !== '$' && hasOwn(data, key)) ||
586586
hasSetupBinding(setupState, key) ||
587587
((normalizedProps = propsOptions[0]) && hasOwn(normalizedProps, key)) ||
588588
hasOwn(ctx, key) ||
589589
hasOwn(publicPropertiesMap, key) ||
590-
hasOwn(appContext.config.globalProperties, key)
590+
hasOwn(appContext.config.globalProperties, key) ||
591+
((cssModules = type.__cssModules) && cssModules[key])
591592
)
592593
},
593594

0 commit comments

Comments
 (0)