提交 bd35b9ad 编写于 作者: Q qiang

fix(mp): 优化小程序插槽节点深度

上级 6056a476
......@@ -237,16 +237,28 @@ describe('mp:compiler-extra', () => {
assertCodegen(
'<component1 v-slot>text</component1>',
'<component1 vue-id="551070e6-1" bind:__l="__l" vue-slots="{{[\'default\']}}"><view>text</view></component1>'
'<component1 vue-id="551070e6-1" bind:__l="__l" vue-slots="{{[\'default\']}}"><block>text</block></component1>'
)
assertCodegen(
'<component1 v-slot:default>text<text>123213</text></component1>',
'<component1 vue-id="551070e6-1" bind:__l="__l" vue-slots="{{[\'default\']}}"><view>text<text>123213</text></view></component1>'
'<component1 vue-id="551070e6-1" bind:__l="__l" vue-slots="{{[\'default\']}}"><block>text<text>123213</text></block></component1>'
)
assertCodegen(
'<component1><template v-slot:left><text></text></template><template v-slot:right><text></text></template></component1>',
'<component1 vue-id="551070e6-1" bind:__l="__l" vue-slots="{{[\'left\',\'right\']}}"><view slot="left"><text></text></view><view slot="right"><text></text></view></component1>'
'<component1 vue-id="551070e6-1" bind:__l="__l" vue-slots="{{[\'left\',\'right\']}}"><text slot="left"></text><text slot="right"></text></component1>'
)
assertCodegen(
'<component1><view>view1</view><view>view2</view></component1>',
'<component1 vue-id="551070e6-1" bind:__l="__l" vue-slots="{{[\'default\']}}"><view>view1</view><view>view2</view></component1>'
)
assertCodegen(
'<component1><template v-slot><view>view1</view><view>view2</view><template></component1>',
'<component1 vue-id="551070e6-1" bind:__l="__l" vue-slots="{{[\'default\']}}"><block><view>view1</view><view>view2</view></block></component1>'
)
assertCodegen(
'<component1><template v-slot:test><view>view1</view><view>view2</view><template></component1>',
'<component1 vue-id="551070e6-1" bind:__l="__l" vue-slots="{{[\'test\']}}"><view slot="test"><view>view1</view><view>view2</view></view></component1>'
)
assertCodegen(
`<my-component>
......@@ -258,7 +270,7 @@ describe('mp:compiler-extra', () => {
<p>Here's some contact info</p>
</template>
</my-component>`,
'<my-component vue-id="551070e6-1" bind:__l="__l" vue-slots="{{[\'default\',\'header\',\'footer\']}}"><view slot="header"><view class="_h1">Here might be a page title</view></view><view slot="footer"><view class="_p">Here\'s some contact info</view></view><view class="_p">A paragraph for the main content.</view></my-component>'
'<my-component vue-id="551070e6-1" bind:__l="__l" vue-slots="{{[\'default\',\'header\',\'footer\']}}"><view class="_h1" slot="header">Here might be a page title</view><view class="_p" slot="footer">Here\'s some contact info</view><view class="_p">A paragraph for the main content.</view></my-component>'
)
})
......
......@@ -48,12 +48,17 @@ function processElement (ast, state, isRoot) {
const slots = []
for (let i = children.length - 1; i >= 0; i--) {
const childElement = children[i]
// <block name="left"></block> => <view name="left"></view>
/**
* 仅百度、字节支持使用 block 作为命名插槽根节点
* 此处为了统一仅忽略默认插槽
* <block slot="left"></block> => <view slot="left"></view>
*/
if (typeof childElement !== 'string' && childElement.attr.slot) {
if (childElement.type === 'block') {
const slot = childElement.attr.slot
if (slot && slot !== 'default' && childElement.type === 'block') {
childElement.type = 'view'
}
slots.push(childElement.attr.slot)
slots.push(slot)
} else {
defaultSlot = true
}
......@@ -78,7 +83,7 @@ function processElement (ast, state, isRoot) {
if (ast.attr.id && ast.attr.id.indexOf('{{') === 0) {
state.tips.add(`id 作为属性保留名,不允许在自定义组件 ${ast.type} 中定义为 props`)
}
if (hasOwn(ast.attr, 'data') && platformName !== 'mp-toutiao') { // 百度中会出现异常情况
if (hasOwn(ast.attr, 'data') && platformName !== 'mp-toutiao') { // 百度中会出现异常情况
// TODO 暂不输出
// state.tips.add(`data 作为属性保留名,不允许在自定义组件 ${ast.type} 中定义为 props`)
}
......
......@@ -337,6 +337,20 @@ function traverseRenderSlot (callExprNode, state) {
}
function traverseResolveScopedSlots (callExprNode, state) {
function single (children, slotName, ignore) {
if (Array.isArray(children) && children.length === 1) {
const child = children[0]
if (!child.type) {
return
}
if (ignore.includes(child.type)) {
return single(child.children, slotName, ignore)
}
child.attr = child.attr || {}
child.attr.slot = slotName
return true
}
}
return callExprNode.arguments[0].elements.map(slotNode => {
let keyProperty = false
let fnProperty = false
......@@ -383,14 +397,18 @@ function traverseResolveScopedSlots (callExprNode, state) {
state
)
}
const node = {
type: 'view',
const children = normalizeChildren(traverseExpr(returnExprNodes, state))
// 除百度、字节外其他小程序仅默认插槽可以支持多个节点
if (single(children, slotName, ['template', 'block'])) {
return children[0]
}
return {
type: 'block',
attr: {
slot: slotName
},
children: normalizeChildren(traverseExpr(returnExprNodes, state))
children
}
return node
})
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册