fix(runtime-core): avoid script setup bindings overwriting reserved ctx properties (#4570)
This commit is contained in:
parent
a31303f835
commit
14fcced281
@ -482,6 +482,54 @@ describe('api: createApp', () => {
|
|||||||
expect(serializeInner(root)).toBe('hello')
|
expect(serializeInner(root)).toBe('hello')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('return property "_" should not overwrite "ctx._", __isScriptSetup: false', () => {
|
||||||
|
const Comp = defineComponent({
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
_: ref(0) // return property "_" should not overwrite "ctx._"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return h('input', {
|
||||||
|
ref: 'input'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const root1 = nodeOps.createElement('div')
|
||||||
|
createApp(Comp).mount(root1)
|
||||||
|
|
||||||
|
expect(
|
||||||
|
`setup() return property "_" should not start with "$" or "_" which are reserved prefixes for Vue internals.`
|
||||||
|
).toHaveBeenWarned()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('return property "_" should not overwrite "ctx._", __isScriptSetup: true', () => {
|
||||||
|
const Comp = defineComponent({
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
_: ref(0), // return property "_" should not overwrite "ctx._"
|
||||||
|
__isScriptSetup: true // mock __isScriptSetup = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return h('input', {
|
||||||
|
ref: 'input'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const root1 = nodeOps.createElement('div')
|
||||||
|
const app = createApp(Comp).mount(root1)
|
||||||
|
|
||||||
|
// trigger
|
||||||
|
app.$refs.input
|
||||||
|
|
||||||
|
expect(
|
||||||
|
`TypeError: Cannot read property '__isScriptSetup' of undefined`
|
||||||
|
).not.toHaveBeenWarned()
|
||||||
|
})
|
||||||
|
|
||||||
// config.compilerOptions is tested in packages/vue since it is only
|
// config.compilerOptions is tested in packages/vue since it is only
|
||||||
// supported in the full build.
|
// supported in the full build.
|
||||||
})
|
})
|
||||||
|
@ -538,20 +538,22 @@ export function exposeSetupStateOnRenderContext(
|
|||||||
) {
|
) {
|
||||||
const { ctx, setupState } = instance
|
const { ctx, setupState } = instance
|
||||||
Object.keys(toRaw(setupState)).forEach(key => {
|
Object.keys(toRaw(setupState)).forEach(key => {
|
||||||
if (!setupState.__isScriptSetup && (key[0] === '$' || key[0] === '_')) {
|
if (!setupState.__isScriptSetup) {
|
||||||
warn(
|
if (key[0] === '$' || key[0] === '_') {
|
||||||
`setup() return property ${JSON.stringify(
|
warn(
|
||||||
key
|
`setup() return property ${JSON.stringify(
|
||||||
)} should not start with "$" or "_" ` +
|
key
|
||||||
`which are reserved prefixes for Vue internals.`
|
)} should not start with "$" or "_" ` +
|
||||||
)
|
`which are reserved prefixes for Vue internals.`
|
||||||
return
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Object.defineProperty(ctx, key, {
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
get: () => setupState[key],
|
||||||
|
set: NOOP
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Object.defineProperty(ctx, key, {
|
|
||||||
enumerable: true,
|
|
||||||
configurable: true,
|
|
||||||
get: () => setupState[key],
|
|
||||||
set: NOOP
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user