From 7e40b3d95376558786a74f4570faefbc0e2462d6 Mon Sep 17 00:00:00 2001 From: fxy060608 Date: Tue, 22 Feb 2022 16:27:54 +0800 Subject: [PATCH] fix(mp): v-for scope (#3263) --- .../uni-mp-compiler/__tests__/scope.spec.ts | 27 ++++++++++++------- .../uni-mp-compiler/src/transforms/utils.ts | 3 +-- .../uni-mp-compiler/src/transforms/vFor.ts | 18 +++---------- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/packages/uni-mp-compiler/__tests__/scope.spec.ts b/packages/uni-mp-compiler/__tests__/scope.spec.ts index 9037507ea..37959a727 100644 --- a/packages/uni-mp-compiler/__tests__/scope.spec.ts +++ b/packages/uni-mp-compiler/__tests__/scope.spec.ts @@ -20,9 +20,9 @@ describe('compiler: scope', () => { ) assert( ``, - ``, + ``, `(_ctx, _cache) => { - return { a: _f(_ctx.items, (item, k0, i0) => { return { a: item.id }; }), b: _f(_ctx.item1, (item1, k1, i1) => { return { a: item1.title }; }) } + return { a: _f(_ctx.items, (item, k0, i0) => { return { a: _f(_ctx.item1, (item1, k1, i1) => { return { a: item1.title }; }), b: item.id }; }) } }` ) assert( @@ -30,6 +30,13 @@ describe('compiler: scope', () => { ``, `(_ctx, _cache) => { return { a: _f(_ctx.weeks, (item, weekIndex, i0) => { return { a: _f(item, (weeks, weeksIndex, i1) => { return { a: weeksIndex, b: weeks.id }; }), b: weekIndex, c: item.id }; }) } +}` + ) + assert( + `{{x+y}}`, + `{{y.a}}`, + `(_ctx, _cache) => { + return { a: _f(2, (x, k0, i0) => { return { a: _f(2, (y, k1, i1) => { return { a: _t(x + y) }; }) }; }) } }` ) }) @@ -52,9 +59,9 @@ describe('compiler: scope', () => { ) assert( `s`, - `s`, + `s`, `(_ctx, _cache) => { - return { a: _f(_ctx.items1, (s, k0, i0) => { return {}; }), b: _f(_ctx.items2, (r, k1, i1) => { return _ctx.a == 2 ? {} : {}; }), c: _ctx.a == 2 } + return { a: _f(_ctx.items1, (s, k0, i0) => { return { a: _f(_ctx.items2, (r, k1, i1) => { return _ctx.a == 2 ? {} : {}; }) }; }), b: _ctx.a == 2 } }` ) }) @@ -68,25 +75,25 @@ describe('compiler: scope', () => { ) assert( `as`, - `as`, + `as`, `(_ctx, _cache) => { - return { a: _f(_ctx.items1, (s, k0, i0) => { return {}; }), b: _f(_ctx.items2, (r, k1, i1) => { return _ctx.a == 2 ? {} : _ctx.b == 3 ? {} : {}; }), c: _ctx.a == 2, d: _ctx.b == 3 } + return { a: _f(_ctx.items1, (s, k0, i0) => { return { a: _f(_ctx.items2, (r, k1, i1) => { return _ctx.a == 2 ? {} : _ctx.b == 3 ? {} : {}; }) }; }), b: _ctx.a == 2, c: _ctx.b == 3 } }` ) }) test('v-for + v-for + v-for + v-if', () => { assert( `s`, - `s`, + `s`, `(_ctx, _cache) => { - return { a: _f(_ctx.items1, (s, k0, i0) => { return { a: _f(_ctx.items3, (t, k2, i2) => { return s == 2 ? {} : {}; }), b: s == 2 }; }), b: _f(_ctx.items2, (r, k1, i1) => { return {}; }) } + return { a: _f(_ctx.items1, (s, k0, i0) => { return { a: _f(_ctx.items2, (r, k1, i1) => { return { a: _f(_ctx.items3, (t, k2, i2) => { return s == 2 ? {} : {}; }) }; }), b: s == 2 }; }) } }` ) assert( `s`, - `s`, + `s`, `(_ctx, _cache) => { - return { a: _f(_ctx.items1, (s, k0, i0) => { return {}; }), b: _f(_ctx.items2, (r, k1, i1) => { return { a: _f(_ctx.items3, (t, k2, i2) => { return r == 2 ? {} : {}; }), b: r == 2 }; }) } + return { a: _f(_ctx.items1, (s, k0, i0) => { return { a: _f(_ctx.items2, (r, k1, i1) => { return { a: _f(_ctx.items3, (t, k2, i2) => { return r == 2 ? {} : {}; }), b: r == 2 }; }) }; }) } }` ) }) diff --git a/packages/uni-mp-compiler/src/transforms/utils.ts b/packages/uni-mp-compiler/src/transforms/utils.ts index b051d4faf..e1034a429 100644 --- a/packages/uni-mp-compiler/src/transforms/utils.ts +++ b/packages/uni-mp-compiler/src/transforms/utils.ts @@ -173,13 +173,12 @@ export function findReferencedScope( return scope } else if (isVForScope(scope)) { if (!findReferenced) { - // 部分情况下(比如包含了自定义组件,组件的 vueId 需要访问 vFor 的 index),只要在 vFor 下,不管有无引用,作用域均绑定在该 vFor 下 return scope } if (isReferencedByIds(node, scope.locals)) { return scope } - return findReferencedScope(node, scope.parent!) + return findReferencedScope(node, scope.parent!, findReferenced) } return scope } diff --git a/packages/uni-mp-compiler/src/transforms/vFor.ts b/packages/uni-mp-compiler/src/transforms/vFor.ts index 1a92978e9..27aebf72a 100644 --- a/packages/uni-mp-compiler/src/transforms/vFor.ts +++ b/packages/uni-mp-compiler/src/transforms/vFor.ts @@ -1,4 +1,5 @@ import { extend, isString } from '@vue/shared' +import { isElementNode } from '@dcloudio/uni-cli-shared' import { createCompilerError, createSimpleExpression, @@ -48,7 +49,6 @@ import { import { CodegenScope, CodegenVForScope } from '../options' import { V_FOR } from '../runtimeHelpers' import { createVSlotCallExpression } from './vSlot' -import { isElementNode, isUserComponent } from '@dcloudio/uni-cli-shared' export type VForOptions = Omit & { sourceExpr?: Expression @@ -118,8 +118,8 @@ export const transformFor = createStructuralDirectiveTransform( const sourceAliasReferencedScope = findReferencedScope( cloneSourceExpr, context.currentScope, - // issues/3263 - !hasUserComponent(node, context) + // vFor 嵌套时,始终保持嵌套关系,issues/3263 + false ) // 寻找子节点中 if 指令作用域 const vIfReferencedScope = findVIfReferencedScope( @@ -219,18 +219,6 @@ export const transformFor = createStructuralDirectiveTransform( } ) as unknown as NodeTransform -function hasUserComponent( - node: ElementNode, - context: TransformContext -): boolean { - if (isUserComponent(node, context)) { - return true - } - return node.children.some( - (node) => isElementNode(node) && hasUserComponent(node, context) - ) -} - function clearExpr(expr: Expression) { Object.keys(expr).forEach((key) => { delete (expr as any)[key] -- GitLab