Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ae60a91

Browse files
committed
fix(compiler-sfc): fix sfc template unref rewrite for class instantiation
close #6483 close #6491
1 parent fda5192 commit ae60a91

File tree

4 files changed

+59
-2
lines changed

4 files changed

+59
-2
lines changed

‎packages/compiler-core/src/babelUtils.ts‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,19 @@ export function isInDestructureAssignment(
146146
return false
147147
}
148148

149+
export function isInNewExpression(parentStack: Node[]): boolean {
150+
let i = parentStack.length
151+
while (i--) {
152+
const p = parentStack[i]
153+
if (p.type === 'NewExpression') {
154+
return true
155+
} else if (p.type !== 'MemberExpression') {
156+
break
157+
}
158+
}
159+
return false
160+
}
161+
149162
export function walkFunctionParams(
150163
node: Function,
151164
onIdent: (id: Identifier) => void,

‎packages/compiler-core/src/transforms/transformExpression.ts‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
} from '../ast'
2020
import {
2121
isInDestructureAssignment,
22+
isInNewExpression,
2223
isStaticProperty,
2324
isStaticPropertyKey,
2425
walkIdentifiers,
@@ -131,6 +132,11 @@ export function processExpression(
131132
// ({ x } = y)
132133
const isDestructureAssignment =
133134
parent && isInDestructureAssignment(parent, parentStack)
135+
const isNewExpression = parent && isInNewExpression(parentStack)
136+
const wrapWithUnref = (raw: string) => {
137+
const wrapped = `${context.helperString(UNREF)}(${raw})`
138+
return isNewExpression ? `(${wrapped})` : wrapped
139+
}
134140

135141
if (
136142
isConst(type) ||
@@ -147,7 +153,7 @@ export function processExpression(
147153
// that assumes the value to be a ref for more efficiency
148154
return isAssignmentLVal || isUpdateArg || isDestructureAssignment
149155
? `${raw}.value`
150-
: `${context.helperString(UNREF)}(${raw})`
156+
: wrapWithUnref(raw)
151157
} else if (type === BindingTypes.SETUP_LET) {
152158
if (isAssignmentLVal) {
153159
// let binding.
@@ -190,7 +196,7 @@ export function processExpression(
190196
// for now
191197
return raw
192198
} else {
193-
return `${context.helperString(UNREF)}(${raw})`
199+
return wrapWithUnref(raw)
194200
}
195201
} else if (type === BindingTypes.PROPS) {
196202
// use __props which is generated by compileScript so in ts mode

‎packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,6 +1028,26 @@ return (_ctx, _cache) => {
10281028
}"
10291029
`;
10301030
1031+
exports[`SFC compile <script setup> > inlineTemplate mode > unref + new expression 1`] = `
1032+
"import { unref as _unref, toDisplayString as _toDisplayString, createElementVNode as _createElementVNode, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
1033+
1034+
import Foo from './foo'
1035+
1036+
export default {
1037+
setup(__props) {
1038+
1039+
1040+
return (_ctx, _cache) => {
1041+
return (_openBlock(), _createElementBlock(_Fragment, null, [
1042+
_createElementVNode("div", null, _toDisplayString(new (_unref(Foo))()), 1 /* TEXT */),
1043+
_createElementVNode("div", null, _toDisplayString(new (_unref(Foo)).Bar()), 1 /* TEXT */)
1044+
], 64 /* STABLE_FRAGMENT */))
1045+
}
1046+
}
1047+
1048+
}"
1049+
`;
1050+
10311051
exports[`SFC compile <script setup> > inlineTemplate mode > v-model codegen 1`] = `
10321052
"import { vModelText as _vModelText, createElementVNode as _createElementVNode, withDirectives as _withDirectives, unref as _unref, isRef as _isRef, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
10331053

‎packages/compiler-sfc/__tests__/compileScript.spec.ts‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,24 @@ describe('SFC compile <script setup>', () => {
650650
),
651651
).not.toThrowError()
652652
})
653+
654+
test('unref + new expression', () => {
655+
const { content } = compile(
656+
`
657+
<script setup>
658+
import Foo from './foo'
659+
</script>
660+
<template>
661+
<div>{{ new Foo() }}</div>
662+
<div>{{ new Foo.Bar() }}</div>
663+
</template>
664+
`,
665+
{ inlineTemplate: true },
666+
)
667+
expect(content).toMatch(`new (_unref(Foo))()`)
668+
expect(content).toMatch(`new (_unref(Foo)).Bar()`)
669+
assertCode(content)
670+
})
653671
})
654672

655673
describe('with TypeScript', () => {

0 commit comments

Comments
 (0)