提交 1b730d2b 编写于 作者: Q qiang

fix(mp): slot name dynamic data (question/82506)

上级 51940f69
......@@ -182,6 +182,30 @@ describe('mp:compiler', () => {
'<view><slot name="one"></slot></view>',
'<view><slot name="one"></slot></view>'
)
assertCodegen(
'<view><slot :name="one"></slot></view>',
'<view><slot name="{{one}}"></slot></view>'
)
assertCodegen(
'<view><slot :name="one+\'test\'"></slot></view>',
'<view><slot name="{{one+\'test\'}}"></slot></view>'
)
assertCodegen(
'<view><slot :name="one" :test="test"></slot></view>',
'<view><slot name="{{one}}"></slot></view>',
'with(this){{$setScopedSlotsParams(one,{"test":test})}}',
{
scopedSlotsCompiler: 'augmented'
}
)
assertCodegen(
'<view><slot :name="one">text</slot></view>',
'<view><block wx:if="{{$slots[one]}}"><slot name="{{one}}"></slot></block><block wx:else>text</block></view>'
)
assertCodegen(
'<view><slot :name="one+\'test\'">text</slot></view>',
'<view><block wx:if="{{$slots[one+\'test\']}}"><slot name="{{one+\'test\'}}"></slot></block><block wx:else>text</block></view>'
)
})
// it('generate slot fallback content', () => {
......
......@@ -15,12 +15,13 @@ module.exports = {
preTransformNode (el, {
warn
}) {
if (el.tag === 'slot' && !el.attrsMap.name) {
const attrsMap = el.attrsMap
if (el.tag === 'slot' && !(attrsMap.name || attrsMap[':name'])) {
el.attrsList.push({
name: 'SLOT_DEFAULT',
value: true
})
el.attrsMap.SLOT_DEFAULT = true
attrsMap.SLOT_DEFAULT = true
}
// 处理 attr
el.attrsList.forEach(attr => {
......@@ -31,11 +32,11 @@ module.exports = {
const origName = attr.name
const newName = origName.replace('.lazy', '')
attr.name = newName
el.attrsMap[newName] = attr.value
delete el.attrsMap[origName]
attrsMap[newName] = attr.value
delete attrsMap[origName]
} else if (onRE.test(attr.name) && !attr.value.trim()) { // 事件为空
attr.value = '__HOLDER__'
el.attrsMap[attr.name] = attr.value
attrsMap[attr.name] = attr.value
}
})
// 暂不支持的指令
......
......@@ -32,7 +32,7 @@ module.exports = function getRenderSlot (path, state) {
const scoped = state.scoped
// TODO 判断是否包含作用域内变量
const renderSlotStatementArray = scoped && scoped.length ? scoped[scoped.length - 1].renderSlotStatementArray : state.renderSlotStatementArray
renderSlotStatementArray.push(t.expressionStatement(t.callExpression(t.identifier('$setScopedSlotsParams'), [t.stringLiteral(name.node.value), valueNode])))
renderSlotStatementArray.push(t.expressionStatement(t.callExpression(t.identifier('$setScopedSlotsParams'), [name.node, valueNode])))
}
// TODO 组件嵌套
}
......@@ -270,7 +270,7 @@ function traverseArrayExpression (arrayExprNodes, state) {
}, [])
}
function genSlotNode (slotName, slotNode, fallbackNodes, state) {
function genSlotNode (slotName, slotNode, fallbackNodes, state, isStaticSlotName = true) {
if (!fallbackNodes || t.isNullLiteral(fallbackNodes)) {
return slotNode
}
......@@ -282,7 +282,7 @@ function genSlotNode (slotName, slotNode, fallbackNodes, state) {
return [{
type: 'block',
attr: {
[prefix + 'if']: '{{$slots.' + slotName + '}}'
[prefix + 'if']: isStaticSlotName ? '{{$slots.' + slotName + '}}' : '{{$slots[' + slotName.replace(/^{{/, '').replace(/}}$/, '') + ']}}'
},
children: [].concat(slotNode)
}, {
......@@ -297,12 +297,9 @@ function genSlotNode (slotName, slotNode, fallbackNodes, state) {
}
function traverseRenderSlot (callExprNode, state) {
if (!t.isStringLiteral(callExprNode.arguments[0])) {
state.errors.add(uniI18n.__('templateCompiler.notSupportDynamicSlotName', { 0: 'v-slot' }))
return
}
const slotName = callExprNode.arguments[0].value
const slotNameNode = callExprNode.arguments[0]
const isStaticSlotName = t.isStringLiteral(slotNameNode)
const slotName = isStaticSlotName ? slotNameNode.value : genCode(slotNameNode)
let deleteSlotName = false // 标记是否组件 slot 手动指定了 name="default"
if (state.options.scopedSlotsCompiler !== 'augmented' && callExprNode.arguments.length > 2) { // 作用域插槽
......@@ -312,6 +309,10 @@ function traverseRenderSlot (callExprNode, state) {
})
deleteSlotName = props.SLOT_DEFAULT && Object.keys(props).length === 1
if (!deleteSlotName) {
if (!isStaticSlotName) {
state.errors.add(uniI18n.__('templateCompiler.notSupportDynamicSlotName', { 0: 'v-slot' }))
return
}
delete props.SLOT_DEFAULT
return genSlotNode(
slotName,
......@@ -334,10 +335,11 @@ function traverseRenderSlot (callExprNode, state) {
delete node.attr.name
}
return genSlotNode(slotName, node, callExprNode.arguments[1], state)
return genSlotNode(slotName, node, callExprNode.arguments[1], state, isStaticSlotName)
}
function traverseResolveScopedSlots (callExprNode, state) {
const options = state.options
function single (children, slotName, ignore) {
if (Array.isArray(children) && children.length === 1) {
const child = children[0]
......@@ -371,14 +373,14 @@ function traverseResolveScopedSlots (callExprNode, state) {
const slotName = keyProperty.value.value
const returnExprNodes = fnProperty.value.body.body[0].argument
const parentNode = callExprNode.$node
if (slotNode.scopedSlotsCompiler !== 'augmented' && !proxyProperty) {
const resourcePath = state.options.resourcePath
if (options.scopedSlotsCompiler !== 'augmented' && slotNode.scopedSlotsCompiler !== 'augmented' && !proxyProperty) {
const resourcePath = options.resourcePath
const ownerName = path.basename(resourcePath, path.extname(resourcePath))
const parentName = parentNode.type
const paramExprNode = fnProperty.value.params[0]
return state.options.platform.resolveScopedSlots(
return options.platform.resolveScopedSlots(
slotName, {
genCode,
generate,
......@@ -398,7 +400,7 @@ function traverseResolveScopedSlots (callExprNode, state) {
state
)
}
if (state.options.scopedSlotsCompiler === 'auto' && slotNode.scopedSlotsCompiler === 'augmented') {
if (options.scopedSlotsCompiler === 'auto' && slotNode.scopedSlotsCompiler === 'augmented') {
parentNode.attr['scoped-slots-compiler'] = 'augmented'
}
const children = normalizeChildren(traverseExpr(returnExprNodes, state))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册