fix(compiler-vapor): member expression with assignment (#146)

This commit is contained in:
Rizumu Ayaka 2024-03-12 15:46:30 +08:00 committed by GitHub
parent ebd3710d72
commit c79629f0ef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 79 additions and 3 deletions

View File

@ -84,6 +84,39 @@ export function render(_ctx) {
}" }"
`; `;
exports[`compiler: vModel transform > should support member expression 1`] = `
"import { vModelText as _vModelText, withDirectives as _withDirectives, delegate as _delegate, template as _template } from 'vue/vapor';
const t0 = _template("<input>")
export function render(_ctx) {
const n0 = t0()
const n1 = t0()
const n2 = t0()
_withDirectives(n0, [[_vModelText, () => _ctx.setupRef.child]])
_withDirectives(n1, [[_vModelText, () => _ctx.setupLet.child]])
_withDirectives(n2, [[_vModelText, () => _ctx.setupMaybeRef.child]])
_delegate(n0, "update:modelValue", () => $event => (_ctx.setupRef.child = $event))
_delegate(n1, "update:modelValue", () => $event => (_ctx.setupLet.child = $event))
_delegate(n2, "update:modelValue", () => $event => (_ctx.setupMaybeRef.child = $event))
return [n0, n1, n2]
}"
`;
exports[`compiler: vModel transform > should support member expression w/ inline 1`] = `
"(() => {
const n0 = t0()
const n1 = t0()
const n2 = t0()
_withDirectives(n0, [[_vModelText, () => setupRef.value.child]])
_withDirectives(n1, [[_vModelText, () => _unref(setupLet).child]])
_withDirectives(n2, [[_vModelText, () => _unref(setupMaybeRef).child]])
_delegate(n0, "update:modelValue", () => $event => (setupRef.value.child = $event))
_delegate(n1, "update:modelValue", () => $event => (_unref(setupLet).child = $event))
_delegate(n2, "update:modelValue", () => $event => (_unref(setupMaybeRef).child = $event))
return [n0, n1, n2]
})()"
`;
exports[`compiler: vModel transform > should support select 1`] = ` exports[`compiler: vModel transform > should support select 1`] = `
"import { vModelSelect as _vModelSelect, withDirectives as _withDirectives, delegate as _delegate, template as _template } from 'vue/vapor'; "import { vModelSelect as _vModelSelect, withDirectives as _withDirectives, delegate as _delegate, template as _template } from 'vue/vapor';
const t0 = _template("<select></select>") const t0 = _template("<select></select>")

View File

@ -1,6 +1,6 @@
import { makeCompile } from './_utils' import { makeCompile } from './_utils'
import { transformChildren, transformElement, transformVModel } from '../../src' import { transformChildren, transformElement, transformVModel } from '../../src'
import { DOMErrorCodes } from '@vue/compiler-dom' import { BindingTypes, DOMErrorCodes } from '@vue/compiler-dom'
const compileWithVModel = makeCompile({ const compileWithVModel = makeCompile({
nodeTransforms: [transformElement, transformChildren], nodeTransforms: [transformElement, transformChildren],
@ -171,4 +171,35 @@ describe('compiler: vModel transform', () => {
expect(code).toMatchSnapshot() expect(code).toMatchSnapshot()
}) })
}) })
test('should support member expression', () => {
const { code } = compileWithVModel(
'<input v-model="setupRef.child" /><input v-model="setupLet.child" /><input v-model="setupMaybeRef.child" />',
{
bindingMetadata: {
setupRef: BindingTypes.SETUP_REF,
setupLet: BindingTypes.SETUP_LET,
setupMaybeRef: BindingTypes.SETUP_MAYBE_REF,
},
},
)
expect(code).toMatchSnapshot()
})
test('should support member expression w/ inline', () => {
const { code } = compileWithVModel(
'<input v-model="setupRef.child" /><input v-model="setupLet.child" /><input v-model="setupMaybeRef.child" />',
{
bindingMetadata: {
setupRef: BindingTypes.SETUP_REF,
setupLet: BindingTypes.SETUP_LET,
setupMaybeRef: BindingTypes.SETUP_MAYBE_REF,
},
inline: true,
},
)
expect(code).toMatchSnapshot()
})
}) })

View File

@ -56,6 +56,7 @@ export function genExpression(
false, false,
parentStack, parentStack,
) )
let hasMemberExpression = false
if (ids.length) { if (ids.length) {
ids.sort((a, b) => a.start! - b.start!) ids.sort((a, b) => a.start! - b.start!)
const [frag, push] = buildCodeFragment() const [frag, push] = buildCodeFragment()
@ -70,6 +71,13 @@ export function genExpression(
const source = rawExpr.slice(start, end) const source = rawExpr.slice(start, end)
const parentStack = parentStackMap.get(id)! const parentStack = parentStackMap.get(id)!
const parent = parentStack[parentStack.length - 1]
hasMemberExpression ||=
parent &&
(parent.type === 'MemberExpression' ||
parent.type === 'OptionalMemberExpression')
push( push(
...genIdentifier( ...genIdentifier(
source, source,
@ -79,9 +87,9 @@ export function genExpression(
end: advancePositionWithClone(node.loc.start, source, end), end: advancePositionWithClone(node.loc.start, source, end),
source, source,
}, },
assignment, hasMemberExpression ? undefined : assignment,
id, id,
parentStack[parentStack.length - 1], parent,
parentStack, parentStack,
), ),
) )
@ -90,6 +98,10 @@ export function genExpression(
push([rawExpr.slice(end), NewlineType.Unknown]) push([rawExpr.slice(end), NewlineType.Unknown])
} }
}) })
if (assignment && hasMemberExpression) {
push(` = ${assignment}`)
}
return frag return frag
} else { } else {
return [[rawExpr, NewlineType.Unknown, loc]] return [[rawExpr, NewlineType.Unknown, loc]]