Skip to content

Commit

Permalink
fix(runtime-core): avoid script setup bindings overwriting reserved c…
Browse files Browse the repository at this point in the history
…tx properties (#4570)
  • Loading branch information
ygj6 committed Sep 16, 2021
1 parent a31303f commit 14fcced
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 14 deletions.
48 changes: 48 additions & 0 deletions packages/runtime-core/__tests__/apiCreateApp.spec.ts
Expand Up @@ -482,6 +482,54 @@ describe('api: createApp', () => {
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
// supported in the full build.
})
30 changes: 16 additions & 14 deletions packages/runtime-core/src/componentPublicInstance.ts
Expand Up @@ -538,20 +538,22 @@ export function exposeSetupStateOnRenderContext(
) {
const { ctx, setupState } = instance
Object.keys(toRaw(setupState)).forEach(key => {
if (!setupState.__isScriptSetup && (key[0] === '$' || key[0] === '_')) {
warn(
`setup() return property ${JSON.stringify(
key
)} should not start with "$" or "_" ` +
`which are reserved prefixes for Vue internals.`
)
return
if (!setupState.__isScriptSetup) {
if (key[0] === '$' || key[0] === '_') {
warn(
`setup() return property ${JSON.stringify(
key
)} should not start with "$" or "_" ` +
`which are reserved prefixes for Vue internals.`
)
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
})
})
}

0 comments on commit 14fcced

Please sign in to comment.