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

fix(mp): scoped slots with attribute node (question/153150) and slot in v-for (question/155008)

上级 6fb6eb98
......@@ -36,7 +36,7 @@ function uniCloudPlugin() {
if (process.env.UNI_PLATFORM === 'h5' &&
!process.env.UNI_SUB_PLATFORM &&
process.env.NODE_ENV === 'production') {
console.warn('发布H5,需要在uniCloud后台操作,绑定安全域名,否则会因为跨域问题而无法访问。教程参考:https://uniapp.dcloud.net.cn/uniCloud/publish.html#useinh5');
console.warn('发布到web端需要在uniCloud后台操作,绑定安全域名,否则会因为跨域问题而无法访问。教程参考:https://uniapp.dcloud.net.cn/uniCloud/publish.html#useinh5');
}
return {};
},
......@@ -55,8 +55,7 @@ function uniCloudPlugin() {
closeBundle() {
if (process.env.UNI_PLATFORM === 'h5' && !process.env.UNI_SSR_CLIENT) {
console.log();
console.log('欢迎将H5站部署到uniCloud前端网页托管平台,高速、免费、安全、省心,详见:');
console.log('https://uniapp.dcloud.io/uniCloud/hosting');
console.log('欢迎将web站点部署到uniCloud前端网页托管平台,高速、免费、安全、省心,详见:https://uniapp.dcloud.io/uniCloud/hosting');
}
},
};
......
......@@ -2,6 +2,13 @@ import { assert } from './testUtils'
describe('compiler: transform scoped slots', () => {
test('basic', () => {
assert(
`<view><slot data="123"/></view>`,
`<view><slot name="d"/></view>`,
`(_ctx, _cache) => {
return { a: _r("d", { data: "123" }) }
}`
)
assert(
`<view><slot :item="item" :index="index"/></view>`,
`<view><slot name="d"/></view>`,
......
......@@ -37,6 +37,13 @@ describe('compiler: transform slot', () => {
`<view wx:for="{{a}}" wx:for-item="item" wx:key="c"><slot name="{{item.a}}"></slot></view>`,
`(_ctx, _cache) => {
return { a: _f(3, (item, index, i0) => { return { a: _d('title' + index + '-' + i0), b: _r(_d('title' + index), { content: { name: 'name' + index } }, i0), c: index }; }) }
}`
)
assert(
`<view v-for="(item,index) in 3" :key="index"><slot :name="item.slot" :content="{name:'name'+index}"></slot></view>`,
`<view wx:for="{{a}}" wx:for-item="item" wx:key="c"><slot name="{{item.a}}"></slot></view>`,
`(_ctx, _cache) => {
return { a: _f(3, (item, index, i0) => { return { a: _d(item.slot), b: _r(_d(item.slot), { content: { name: 'name' + index } }, i0), c: index }; }) }
}`
)
})
......
......@@ -19,12 +19,14 @@ import { RENDER_SLOT } from '../runtimeHelpers'
import { genExpr } from '../codegen'
import { isScopedSlotVFor, isVForScope, TransformContext } from '../transform'
import { processProps } from './transformElement'
import { removeAttribute, rewriteExpression } from './utils'
import { isReferencedByIds, removeAttribute, rewriteExpression } from './utils'
import {
createAttributeNode,
createBindDirectiveNode,
isDirectiveNode,
} from '@dcloudio/uni-cli-shared'
import { DYNAMIC_SLOT } from '..'
import { parseExpr } from '../ast'
export function rewriteSlot(node: SlotOutletNode, context: TransformContext) {
let slotName: string | ExpressionNode = `"${SLOT_DEFAULT_NAME}"`
......@@ -53,13 +55,21 @@ export function rewriteSlot(node: SlotOutletNode, context: TransformContext) {
}
if (p.name === 'bind' && isStaticArgOf(p.arg, 'name')) {
if (p.exp) {
const slotKey = parseScopedSlotKey(context)
// renderSlot 第三个参数已经传了 slotKey
slotName = createCompoundExpression([
context.helperString(DYNAMIC_SLOT) + '(',
p.exp,
')',
])
let slotKey
debugger
const keys = parseVForKeyAlias(context)
if (keys.length) {
const babelNode = parseExpr(p.exp, context)
// 在 v-for 中,判断是否插槽名使用 v-for 的 key 变量
if (babelNode && isReferencedByIds(babelNode, keys)) {
slotKey = parseScopedSlotKey(context)
}
}
p.exp = rewriteExpression(
createCompoundExpression([
context.helperString(DYNAMIC_SLOT) + '(',
......@@ -90,10 +100,8 @@ export function rewriteSlot(node: SlotOutletNode, context: TransformContext) {
processProps(node, context, nonNameProps)
const properties: string[] = []
nonNameProps.forEach((prop) => {
if (prop.type === NodeTypes.DIRECTIVE && prop.name === 'bind') {
const property = transformProperty(prop, context)
property && properties.push(property)
}
const property = transformProperty(prop, context)
property && properties.push(property)
})
if (properties.length) {
transformScopedSlotName(node, context)
......@@ -174,7 +182,19 @@ function createScopedSlotDirectiveNode(
return dir
}
function parseScopedSlotKey(context: TransformContext) {
function parseVForKeyAlias(context: TransformContext) {
let { currentScope } = context
const keys: string[] = []
while (currentScope) {
if (isVForScope(currentScope) && !isScopedSlotVFor(currentScope)) {
keys.push(currentScope.keyAlias)
}
currentScope = currentScope.parent!
}
return keys
}
function parseVForIndexes(context: TransformContext) {
let { currentScope } = context
const indexes: string[] = []
while (currentScope) {
......@@ -183,22 +203,39 @@ function parseScopedSlotKey(context: TransformContext) {
}
currentScope = currentScope.parent!
}
return indexes
}
function parseSlotKeyByVForIndexes(indexes: string[]) {
return indexes.reverse().join(`+'-'+`)
}
function parseScopedSlotKey(context: TransformContext) {
const indexes = parseVForIndexes(context)
const inFor = !!indexes.length
if (inFor) {
return indexes.reverse().join(`+'-'+`)
return parseSlotKeyByVForIndexes(indexes)
}
}
function transformProperty(dir: DirectiveNode, context: TransformContext) {
if (!dir.arg || !dir.exp) {
return
}
function transformProperty(
dir: DirectiveNode | AttributeNode,
_: TransformContext
) {
if (isDirectiveNode(dir)) {
if (!dir.arg || !dir.exp) {
return
}
const isStaticArg =
dir.arg.type === NodeTypes.SIMPLE_EXPRESSION && dir.arg.isStatic
const isStaticArg =
dir.arg.type === NodeTypes.SIMPLE_EXPRESSION && dir.arg.isStatic
if (isStaticArg) {
return `${(dir.arg as SimpleExpressionNode).content}:${genExpr(dir.exp)}`
if (isStaticArg) {
return `${(dir.arg as SimpleExpressionNode).content}:${genExpr(dir.exp)}`
}
return `[${genExpr(dir.arg)}||'']:${genExpr(dir.exp)}`
}
if (dir.value) {
return `${dir.name}:${genExpr(dir.value)}`
}
return `[${genExpr(dir.arg)}||'']:${genExpr(dir.exp)}`
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册