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

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

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