Skip to content

Commit

Permalink
dx(runtime-core): warn if this is used in a <script setup> templa…
Browse files Browse the repository at this point in the history
…te (#7866)
  • Loading branch information
skirtles-code authored Nov 10, 2023
1 parent 5a41231 commit f01afda
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
21 changes: 21 additions & 0 deletions packages/runtime-core/__tests__/rendererComponent.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -354,4 +354,25 @@ describe('renderer: component', () => {
expect(serializeInner(root)).toBe(`<h1>1</h1>`)
expect(spy).toHaveBeenCalledTimes(2)
})

it('should warn accessing `this` in a <script setup> template', () => {
const App = {
setup() {
return {
__isScriptSetup: true
}
},

render(this: any) {
return this.$attrs.id
}
}

const root = nodeOps.createElement('div')
render(h(App), root)

expect(
`Property '$attrs' was accessed via 'this'. Avoid using 'this' in templates.`
).toHaveBeenWarned()
})
})
17 changes: 16 additions & 1 deletion packages/runtime-core/src/componentRenderUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,24 @@ export function renderComponentRoot(
// withProxy is a proxy with a different `has` trap only for
// runtime-compiled render functions using `with` block.
const proxyToUse = withProxy || proxy
// 'this' isn't available in production builds with `<script setup>`,
// so warn if it's used in dev.
const thisProxy =
__DEV__ && setupState.__isScriptSetup
? new Proxy(proxyToUse!, {
get(target, key, receiver) {
warn(
`Property '${String(
key
)}' was accessed via 'this'. Avoid using 'this' in templates.`
)
return Reflect.get(target, key, receiver)
}
})
: proxyToUse
result = normalizeVNode(
render!.call(
proxyToUse,
thisProxy,
proxyToUse!,
renderCache,
props,
Expand Down

0 comments on commit f01afda

Please sign in to comment.