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

fix(mp): Scoped Slots with name and fallback content + v-for (#3587)

上级 977770e0
......@@ -60,6 +60,15 @@ describe('compiler: transform scoped slots', () => {
`<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: _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 }) }
}`
)
})
test('names slots with fallback content + v-for', () => {
assert(
`<button v-for="item in 1" :key="item"><slot name="text" :item="item">Submit</slot></button>`,
`<button wx:for="{{a}}" wx:for-item="item" wx:key="c"><block wx:if="{{$slots.text}}"><slot name="{{item.a}}"></slot></block><block wx:else>Submit</block></button>`,
`(_ctx, _cache) => {
return { a: _f(1, (item, k0, i0) => { return { a: "text-" + i0, b: _r("text", { item: item }, i0), c: item }; }) }
}`
)
})
......
......@@ -2,6 +2,7 @@ import { hyphenate } from '@vue/shared'
import { SLOT_DEFAULT_NAME, dynamicSlotName } from '@dcloudio/uni-shared'
import {
formatMiniProgramEvent,
isAttributeNode,
isElementNode,
isUserComponent,
MiniProgramCompilerOptions,
......@@ -22,13 +23,15 @@ import {
TemplateNode,
TextNode,
} from '@vue/compiler-core'
import { TemplateCodegenOptions } from '../options'
import type { TemplateCodegenOptions } from '../options'
import type { NameScopedSlotDirectiveNode } from '../transforms/transformSlot'
import { genExpr } from '../codegen'
import { ForElementNode, isForElementNode } from '../transforms/vFor'
import { IfElementNode, isIfElementNode } from '../transforms/vIf'
import { findSlotName } from '../transforms/vSlot'
import { TransformContext } from '../transform'
import { ATTR_VUE_PROPS } from '../transforms/utils'
interface TemplateCodegenContext {
code: string
directive: string
......@@ -165,13 +168,19 @@ function genSlot(node: SlotOutletNode, context: TemplateCodegenContext) {
push(`<block`)
const nameProp = findProp(node, 'name')
genVIf(
`$slots.` +
(nameProp?.type === NodeTypes.ATTRIBUTE && nameProp.value?.content
? nameProp.value.content
: SLOT_DEFAULT_NAME),
context
)
let name = SLOT_DEFAULT_NAME
if (nameProp) {
if (isAttributeNode(nameProp)) {
if (nameProp.value?.content) {
name = nameProp.value.content
}
} else {
if ((nameProp as NameScopedSlotDirectiveNode).slotName) {
name = (nameProp as NameScopedSlotDirectiveNode).slotName
}
}
}
genVIf(`$slots.${name}`, context)
push(`>`)
genElement(node, context)
push(`</block>`)
......
......@@ -143,17 +143,30 @@ function transformScopedSlotName(
props.splice(
props.indexOf(nameProps),
1,
createBindDirectiveNode(
'name',
rewriteExpression(
createSimpleExpression(`"${nameProps.value.content}-"+` + slotKey),
context
).content
)
createScopedSlotDirectiveNode(nameProps.value.content, slotKey, context)
)
}
}
export interface NameScopedSlotDirectiveNode extends DirectiveNode {
slotName: string
}
function createScopedSlotDirectiveNode(
name: string,
slotKey: string,
context: TransformContext
): NameScopedSlotDirectiveNode {
const dir = createBindDirectiveNode(
'name',
rewriteExpression(createSimpleExpression(`"${name}-"+` + slotKey), context)
.content
) as NameScopedSlotDirectiveNode
// 存储原始的 slot 名称
dir.slotName = name
return dir
}
function parseScopedSlotKey(context: TransformContext) {
let { currentScope } = context
const indexs: string[] = []
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册