Kaynağa Gözat

fix(compiler-sfc): fix template expression assignment codegen for script setup let refs (#3626)

fix #3625
edison 4 yıl önce
ebeveyn
işleme
2c7bd42801

+ 2 - 2
packages/compiler-core/src/transforms/transformExpression.ts

@@ -143,14 +143,14 @@ export function processExpression(
           // let is a local non-ref value, and we need to replicate the
           // right hand side value.
           // x = y --> isRef(x) ? x.value = y : x = y
-          const rVal = (parent as AssignmentExpression).right
+          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)
           )
           return `${context.helperString(IS_REF)}(${raw})${
             context.isTS ? ` //@ts-ignore\n` : ``
-          } ? ${raw}.value = ${rExpString} : ${raw}`
+          } ? ${raw}.value ${operator} ${rExpString} : ${raw}`
         } else if (isUpdateArg) {
           // make id replace parent in the code range so the raw update operator
           // is removed

+ 7 - 0
packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap

@@ -361,6 +361,7 @@ export default {
         const count = ref(0)
         const maybe = foo()
         let lett = 1
+        let v = ref(1)
         
 return (_ctx, _cache) => {
   return (_openBlock(), _createBlock(_Fragment, null, [
@@ -372,6 +373,12 @@ return (_ctx, _cache) => {
     }),
     _createVNode(\\"div\\", {
       onClick: _cache[3] || (_cache[3] = $event => (_isRef(lett) ? lett.value = count.value : lett = count.value))
+    }),
+    _createVNode(\\"div\\", {
+      onClick: _cache[4] || (_cache[4] = $event => (_isRef(v) ? v.value += 1 : v += 1))
+    }),
+    _createVNode(\\"div\\", {
+      onClick: _cache[5] || (_cache[5] = $event => (_isRef(v) ? v.value -= 1 : v -= 1))
     })
   ], 64 /* STABLE_FRAGMENT */))
 }

+ 5 - 0
packages/compiler-sfc/__tests__/compileScript.spec.ts

@@ -300,11 +300,14 @@ const myEmit = defineEmit(['foo', 'bar'])
         const count = ref(0)
         const maybe = foo()
         let lett = 1
+        let v = ref(1)
         </script>
         <template>
           <div @click="count = 1"/>
           <div @click="maybe = count"/>
           <div @click="lett = count"/>
+          <div @click="v += 1"/>
+          <div @click="v -= 1"/>
         </template>
         `,
         { inlineTemplate: true }
@@ -317,6 +320,8 @@ const myEmit = defineEmit(['foo', 'bar'])
       expect(content).toMatch(
         `_isRef(lett) ? lett.value = count.value : lett = count.value`
       )
+      expect(content).toMatch(`_isRef(v) ? v.value += 1 : v += 1`)
+      expect(content).toMatch(`_isRef(v) ? v.value -= 1 : v -= 1`)
       assertCode(content)
     })