]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip(vapor): support default values in v-for destructure
authorEvan You <evan@vuejs.org>
Thu, 30 Jan 2025 13:51:48 +0000 (21:51 +0800)
committerEvan You <evan@vuejs.org>
Thu, 30 Jan 2025 13:51:48 +0000 (21:51 +0800)
packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap
packages/compiler-vapor/__tests__/transforms/vFor.spec.ts
packages/compiler-vapor/src/generators/for.ts
packages/runtime-vapor/src/apiCreateFor.ts
packages/runtime-vapor/src/index.ts

index 93be46fc7edf28632f48ec9acf49d15900e4e671..694b804cd4b2a7259f9786c2246386fc971f5312 100644 (file)
@@ -109,6 +109,20 @@ export function render(_ctx) {
 }"
 `;
 
+exports[`compiler: v-for > v-for aliases w/ complex expressions 1`] = `
+"import { getDefaultValue as _getDefaultValue, setText as _setText, renderEffect as _renderEffect, createFor as _createFor, template as _template } from 'vue';
+const t0 = _template("<div></div>", true)
+
+export function render(_ctx) {
+  const n0 = _createFor(() => (_ctx.list), (_ctx0) => {
+    const n2 = t0()
+    _renderEffect(() => _setText(n2, _getDefaultValue(_ctx._ctx0[0].value.foo, _ctx.bar) + _ctx.bar + _ctx.baz + _getDefaultValue(_ctx._ctx0[0].value.baz[0], _ctx.quux) + _ctx.quux))
+    return n2
+  })
+  return n0
+}"
+`;
+
 exports[`compiler: v-for > w/o value 1`] = `
 "import { createFor as _createFor, template as _template } from 'vue';
 const t0 = _template("<div>item</div>", true)
index 59998d844ba8325aa4e60cf18d609664f6a3f8a8..0e2a7bd826ee01f578c04340fd2ed0d1e35b4143 100644 (file)
@@ -239,16 +239,18 @@ describe('compiler: v-for', () => {
     })
   })
 
-  test.todo('v-for aliases w/ complex expressions', () => {
+  test('v-for aliases w/ complex expressions', () => {
     const { code, ir } = compileWithVFor(
       `<div v-for="({ foo = bar, baz: [qux = quux] }) in list">
         {{ foo + bar + baz + qux + quux }}
       </div>`,
     )
     expect(code).matchSnapshot()
-    expect(code).contains(`([{ foo = bar, baz: [qux = quux] }]) => [foo, qux]`)
-    expect(code).contains(
-      `_ctx0[0] + _ctx.bar + _ctx.baz + _ctx0[1] + _ctx.quux`,
+    expect(code).toContain(
+      `_getDefaultValue(_ctx._ctx0[0].value.foo, _ctx.bar)`,
+    )
+    expect(code).toContain(
+      `_getDefaultValue(_ctx._ctx0[0].value.baz[0], _ctx.quux)`,
     )
     expect(ir.block.operation[0]).toMatchObject({
       type: IRNodeTypes.FOR,
index 1d2b379e7b7922082d5823d4437cb2910ccc2889..c927aa8e4a63e864a367ac9fd8e7ba89f5aaee3d 100644 (file)
@@ -34,6 +34,7 @@ export function genFor(
     let path = `${propsName}[0].value${pathInfo ? pathInfo.path : ''}`
     if (pathInfo) {
       if (pathInfo.helper) {
+        idMap[pathInfo.helper] = null
         path = `${pathInfo.helper}(${path}, ${pathInfo.helperArgs})`
       }
       if (pathInfo.dynamic) {
@@ -147,6 +148,20 @@ export function genFor(
                       .join(', ') +
                     ']'
                 }
+
+                // default value
+                if (
+                  child.type === 'AssignmentPattern' &&
+                  (parent.type === 'ObjectProperty' ||
+                    parent.type === 'ArrayPattern')
+                ) {
+                  isDynamic = true
+                  helper = context.helper('getDefaultValue')
+                  helperArgs = value.content.slice(
+                    child.right.start! - 1,
+                    child.right.end! - 1,
+                  )
+                }
               }
               map.set(id.name, { path, dynamic: isDynamic, helper, helperArgs })
             }
index ceff769669ee7a62f9e5bb9f2e23be79990b04aa..72d038b0a8423c094071b8df3b76db9c06692a2f 100644 (file)
@@ -389,3 +389,7 @@ export function getRestElement(val: any, keys: string[]): any {
   }
   return res
 }
+
+export function getDefaultValue(val: any, defaultVal: any): any {
+  return val === undefined ? defaultVal : val
+}
index 8e4679a33498eef4b0d256b67637f7f94c10b642..40b4b82c3e02e90580650a86ce65f64b7615a7b8 100644 (file)
@@ -22,5 +22,10 @@ export {
 } from './dom/prop'
 export { on, delegate, delegateEvents, setDynamicEvents } from './dom/event'
 export { createIf } from './apiCreateIf'
-export { createFor, createForSlots, getRestElement } from './apiCreateFor'
+export {
+  createFor,
+  createForSlots,
+  getRestElement,
+  getDefaultValue,
+} from './apiCreateFor'
 export { createTemplateRefSetter } from './apiTemplateRef'