// function params
asParams = false,
// v-on handler values may contain multiple statements
- asRawStatements = false
+ asRawStatements = false,
+ localVars: Record<string, number> = Object.create(context.identifiers)
): ExpressionNode {
if (__BROWSER__) {
if (__DEV__) {
const isDestructureAssignment =
parent && isInDestructureAssignment(parent, parentStack)
- if (type === BindingTypes.SETUP_CONST) {
+ if (type === BindingTypes.SETUP_CONST || localVars[raw]) {
return raw
} else if (type === BindingTypes.SETUP_REF) {
return `${raw}.value`
const { right: rVal, operator } = parent as AssignmentExpression
const rExp = rawExp.slice(rVal.start! - 1, rVal.end! - 1)
const rExpString = stringifyExpression(
- processExpression(createSimpleExpression(rExp, false), context)
+ processExpression(
+ createSimpleExpression(rExp, false),
+ context,
+ false,
+ false,
+ knownIds
+ )
)
return `${context.helperString(IS_REF)}(${raw})${
context.isTS ? ` //@ts-ignore\n` : ``
return `$${type}.${raw}`
}
}
+
// fallback to ctx
return `_ctx.${raw}`
}
}
type QualifiedId = Identifier & PrefixMeta
-
const ids: QualifiedId[] = []
const parentStack: Node[] = []
const knownIds: Record<string, number> = Object.create(context.identifiers)
}"
`;
-exports[`SFC compile <script setup> defineProps/defineEmits in multi-variable decalration (full removal) 1`] = `
+exports[`SFC compile <script setup> defineProps/defineEmits in multi-variable declaration (full removal) 1`] = `
"export default {
props: ['item'],
emits: ['a'],
}"
`;
-exports[`SFC compile <script setup> defineProps/defineEmits in multi-variable decalration 1`] = `
+exports[`SFC compile <script setup> defineProps/defineEmits in multi-variable declaration 1`] = `
"export default {
props: ['item'],
emits: ['a'],
`;
exports[`SFC compile <script setup> inlineTemplate mode template assignment expression codegen 1`] = `
-"import { createElementVNode as _createElementVNode, isRef as _isRef, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
+"import { createElementVNode as _createElementVNode, isRef as _isRef, unref as _unref, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from \\"vue\\"
import { ref } from 'vue'
}),
_createElementVNode(\\"div\\", {
onClick: _cache[4] || (_cache[4] = $event => (_isRef(v) ? v.value -= 1 : v -= 1))
+ }),
+ _createElementVNode(\\"div\\", {
+ onClick: _cache[5] || (_cache[5] = () => {
+ let a = '' + _unref(lett)
+ _isRef(v) ? v.value = a : v = a
+ })
+ }),
+ _createElementVNode(\\"div\\", {
+ onClick: _cache[6] || (_cache[6] = () => {
+ // nested scopes
+ (()=>{
+ let x = _ctx.a
+ (()=>{
+ let z = x
+ let z2 = z
+ })
+ let lz = _ctx.z
+ })
+ _isRef(v) ? v.value = _ctx.a : v = _ctx.a
+ })
})
], 64 /* STABLE_FRAGMENT */))
}
emits: ['foo', 'bar'],`)
})
- test('defineProps/defineEmits in multi-variable decalration', () => {
+ test('defineProps/defineEmits in multi-variable declaration', () => {
const { content } = compile(`
<script setup>
const props = defineProps(['item']),
expect(content).toMatch(`emits: ['a'],`)
})
- test('defineProps/defineEmits in multi-variable decalration (full removal)', () => {
+ test('defineProps/defineEmits in multi-variable declaration (full removal)', () => {
const { content } = compile(`
<script setup>
const props = defineProps(['item']),
<div @click="lett = count"/>
<div @click="v += 1"/>
<div @click="v -= 1"/>
+ <div @click="() => {
+ let a = '' + lett
+ v = a
+ }"/>
+ <div @click="() => {
+ // nested scopes
+ (()=>{
+ let x = a
+ (()=>{
+ let z = x
+ let z2 = z
+ })
+ let lz = z
+ })
+ v = a
+ }"/>
</template>
`,
{ inlineTemplate: true }
)
expect(content).toMatch(`_isRef(v) ? v.value += 1 : v += 1`)
expect(content).toMatch(`_isRef(v) ? v.value -= 1 : v -= 1`)
+ expect(content).toMatch(`_isRef(v) ? v.value = a : v = a`)
+ expect(content).toMatch(`_isRef(v) ? v.value = _ctx.a : v = _ctx.a`)
assertCode(content)
})
/**
* check defaults. If the default object is an object literal with only
* static properties, we can directly generate more optimzied default
- * decalrations. Otherwise we will have to fallback to runtime merging.
+ * declarations. Otherwise we will have to fallback to runtime merging.
*/
function checkStaticDefaults() {
return (
}
}
- // walk decalrations to record declared bindings
+ // walk declarations to record declared bindings
if (
(node.type === 'VariableDeclaration' ||
node.type === 'FunctionDeclaration' ||
* })
* ```
*
- * Equivalent type-based decalration:
+ * Equivalent type-based declaration:
* ```ts
* // will be compiled into equivalent runtime declarations
* const props = defineProps<{
* const emit = defineEmits(['change', 'update'])
* ```
*
- * Example type-based decalration:
+ * Example type-based declaration:
* ```ts
* const emit = defineEmits<{
* (event: 'change'): void
/**
* Vue `<script setup>` compiler macro for providing props default values when
- * using type-based `defineProps` decalration.
+ * using type-based `defineProps` declaration.
*
* Example usage:
* ```ts