Răsfoiți Sursa

wip(vapor): support default values in v-for destructure

Evan You 1 an în urmă
părinte
comite
c89e01efbf

+ 14 - 0
packages/compiler-vapor/__tests__/transforms/__snapshots__/vFor.spec.ts.snap

@@ -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)

+ 6 - 4
packages/compiler-vapor/__tests__/transforms/vFor.spec.ts

@@ -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,

+ 15 - 0
packages/compiler-vapor/src/generators/for.ts

@@ -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 })
             }

+ 4 - 0
packages/runtime-vapor/src/apiCreateFor.ts

@@ -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
+}

+ 6 - 1
packages/runtime-vapor/src/index.ts

@@ -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'