提交 2cc7d59a 编写于 作者: fxy060608's avatar fxy060608

fix(mp): v-for + component (#3263)

上级 ad1b719f
import { assert } from './testUtils'
describe('compiler: transform scoped slots', () => {
test('basic', () => {
test('scoped + v-for + component', () => {
assert(
`<view><slot :item="item" :index="index"/></view>`,
`<view><slot name="d"/></view>`,
`<MyComponent :dataList="dataList">
<template v-slot:default="slotProps">
<view>
<view v-for="(item, key) in dataList" :key="key">
<test>{{ item.title }}</test>
</view>
</view>
</template>
</MyComponent>`,
`<my-component u-s="{{['d']}}" u-i="2a9ec0b0-0" u-p="{{b}}"><view wx:for="{{a}}" wx:for-item="slotProps" wx:key="b" slot="{{slotProps.c}}"><view><view wx:for="{{slotProps.a}}" wx:for-item="item" wx:key="c"><test u-s="{{['d']}}" u-i="{{item.b}}">{{item.a}}</test></view></view></view></my-component>`,
`(_ctx, _cache) => {
return { a: _r("d", { item: _ctx.item, index: _ctx.index }) }
}`
)
})
test('named slots', () => {
assert(
`<view><slot name="header" :item="item" :index="index"/></view>`,
`<view><slot name="header"/></view>`,
`(_ctx, _cache) => {
return { a: _r("header", { item: _ctx.item, index: _ctx.index }) }
}`
)
})
test('named slots + v-if', () => {
assert(
`<view><slot v-if="ok" name="header" :item="item" :index="index"/></view>`,
`<view><slot wx:if="{{a}}" name="header"/></view>`,
`(_ctx, _cache) => {
return _e({ a: _ctx.ok }, _ctx.ok ? { b: _r("header", { item: _ctx.item, index: _ctx.index }) } : {})
return { a: _w((slotProps, s0, i0) => { return { a: _f(_ctx.dataList, (item, key, i1) => { return { a: _t(item.title), b: '2a9ec0b0-1' + '-' + i0 + '-' + i1 + ',' + '2a9ec0b0-0', c: key }; }), b: i0, c: s0 }; }, { name: 'd', path: 'a', vueId: '2a9ec0b0-0' }), b: _p({ dataList: _ctx.dataList }) }
}`
)
})
......
......@@ -166,11 +166,16 @@ export function rewriteExpression(
export function findReferencedScope(
node: Expression,
scope: CodegenScope
scope: CodegenScope,
findReferenced: boolean = true
): CodegenScope {
if (isVIfScope(scope)) {
return scope
} else if (isVForScope(scope)) {
if (!findReferenced) {
// 部分情况下(比如包含了自定义组件,组件的 vueId 需要访问 vFor 的 index),只要在 vFor 下,不管有无引用,作用域均绑定在该 vFor 下
return scope
}
if (isReferencedByIds(node, scope.locals)) {
return scope
}
......
......@@ -48,7 +48,7 @@ import {
import { CodegenScope, CodegenVForScope } from '../options'
import { V_FOR } from '../runtimeHelpers'
import { createVSlotCallExpression } from './vSlot'
import { isElementNode } from '@dcloudio/uni-cli-shared'
import { isElementNode, isUserComponent } from '@dcloudio/uni-cli-shared'
export type VForOptions = Omit<ForParseResult, 'tagType'> & {
sourceExpr?: Expression
......@@ -117,7 +117,9 @@ export const transformFor = createStructuralDirectiveTransform(
const sourceAliasReferencedScope = findReferencedScope(
cloneSourceExpr,
context.currentScope
context.currentScope,
// issues/3263
!hasUserComponent(node, context)
)
// 寻找子节点中 if 指令作用域
const vIfReferencedScope = findVIfReferencedScope(
......@@ -217,6 +219,18 @@ 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]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册