فهرست منبع

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

Rizumu Ayaka 2 سال پیش
والد
کامیت
c79629f0ef

+ 33 - 0
packages/compiler-vapor/__tests__/transforms/__snapshots__/vModel.spec.ts.snap

@@ -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`] = `
 "import { vModelSelect as _vModelSelect, withDirectives as _withDirectives, delegate as _delegate, template as _template } from 'vue/vapor';
 const t0 = _template("<select></select>")

+ 32 - 1
packages/compiler-vapor/__tests__/transforms/vModel.spec.ts

@@ -1,6 +1,6 @@
 import { makeCompile } from './_utils'
 import { transformChildren, transformElement, transformVModel } from '../../src'
-import { DOMErrorCodes } from '@vue/compiler-dom'
+import { BindingTypes, DOMErrorCodes } from '@vue/compiler-dom'
 
 const compileWithVModel = makeCompile({
   nodeTransforms: [transformElement, transformChildren],
@@ -171,4 +171,35 @@ describe('compiler: vModel transform', () => {
       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()
+  })
 })

+ 14 - 2
packages/compiler-vapor/src/generators/expression.ts

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