You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

187 lines
7.2 KiB

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rewriteSlot = void 0;
const compiler_core_1 = require("@vue/compiler-core");
const shared_1 = require("@vue/shared");
const uni_shared_1 = require("@dcloudio/uni-shared");
const runtimeHelpers_1 = require("../runtimeHelpers");
const codegen_1 = require("../codegen");
const transform_1 = require("../transform");
const transformElement_1 = require("./transformElement");
const utils_1 = require("./utils");
const uni_cli_shared_1 = require("@dcloudio/uni-cli-shared");
const __1 = require("..");
const ast_1 = require("../ast");
function rewriteSlot(node, context) {
let slotName = `"${uni_shared_1.SLOT_DEFAULT_NAME}"`;
let hasOtherDir = false;
const nonNameProps = [];
const { props } = node;
// 默认插槽强制设置name
if (!(0, compiler_core_1.findProp)(node, 'name')) {
props.unshift((0, uni_cli_shared_1.createAttributeNode)('name', 'default'));
}
for (let i = 0; i < props.length; i++) {
const p = props[i];
if (p.type === 6 /* NodeTypes.ATTRIBUTE */) {
if (p.value) {
if (p.name === 'name') {
p.value.content = (0, uni_shared_1.dynamicSlotName)(p.value.content);
slotName = JSON.stringify(p.value.content);
}
else {
p.name = (0, shared_1.camelize)(p.name);
nonNameProps.push(p);
}
}
}
else {
if (p.name !== 'bind') {
hasOtherDir = true;
}
if (p.name === 'bind' && (0, compiler_core_1.isStaticArgOf)(p.arg, 'name')) {
if (p.exp) {
slotName = (0, compiler_core_1.createCompoundExpression)([
context.helperString(__1.DYNAMIC_SLOT) + '(',
p.exp,
')',
]);
let slotKey;
const keys = parseVForKeyAlias(context);
if (keys.length) {
const babelNode = (0, ast_1.parseExpr)(p.exp, context);
// 在 v-for 中,判断是否插槽名使用 v-for 的 key 变量
if (babelNode && (0, utils_1.isReferencedByIds)(babelNode, keys)) {
slotKey = parseScopedSlotKey(context);
}
}
p.exp = (0, utils_1.rewriteExpression)((0, compiler_core_1.createCompoundExpression)([
context.helperString(__1.DYNAMIC_SLOT) + '(',
p.exp,
slotKey ? `+'-'+` + slotKey : '',
')',
]), context);
}
}
else {
if (p.name === 'bind' && p.arg && (0, compiler_core_1.isStaticExp)(p.arg)) {
p.arg.content = (0, shared_1.camelize)(p.arg.content);
}
nonNameProps.push(p);
}
}
}
if (hasOtherDir) {
context.onError((0, compiler_core_1.createCompilerError)(36 /* ErrorCodes.X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, node.loc));
}
if (nonNameProps.length > 0) {
(0, transformElement_1.processProps)(node, context, nonNameProps);
const properties = [];
nonNameProps.forEach((prop) => {
const property = transformProperty(prop, context);
property && properties.push(property);
});
if (properties.length) {
transformScopedSlotName(node, context);
const vForIndexAlias = parseVForIndexAlias(context);
(0, utils_1.rewriteExpression)((0, compiler_core_1.createCompoundExpression)([
context.helperString(runtimeHelpers_1.RENDER_SLOT) + '(',
slotName,
',',
`{${properties.join(',')}}`,
`${vForIndexAlias ? ',' + parseScopedSlotKey(context) : ''}`,
')',
]), context);
}
else {
// 非作用域默认插槽直接移除命名
if (slotName === `"${uni_shared_1.SLOT_DEFAULT_NAME}"`) {
(0, utils_1.removeAttribute)(node, 'name');
}
}
}
else {
// 非作用域默认插槽直接移除命名
if (slotName === `"${uni_shared_1.SLOT_DEFAULT_NAME}"`) {
(0, utils_1.removeAttribute)(node, 'name');
}
}
}
exports.rewriteSlot = rewriteSlot;
function parseVForIndexAlias(context) {
let { currentScope } = context;
while (currentScope) {
if ((0, transform_1.isVForScope)(currentScope) && !(0, transform_1.isScopedSlotVFor)(currentScope)) {
return currentScope.indexAlias;
}
currentScope = currentScope.parent;
}
}
function transformScopedSlotName(node, context) {
if (!context.miniProgram.slot.dynamicSlotNames) {
return;
}
const slotKey = parseScopedSlotKey(context);
if (!slotKey) {
return;
}
const nameProps = (0, compiler_core_1.findProp)(node, 'name');
if (nameProps && nameProps.type === 6 /* NodeTypes.ATTRIBUTE */ && nameProps.value) {
const { props } = node;
props.splice(props.indexOf(nameProps), 1, createScopedSlotDirectiveNode(nameProps.value.content, slotKey, context));
}
}
function createScopedSlotDirectiveNode(name, slotKey, context) {
const dir = (0, uni_cli_shared_1.createBindDirectiveNode)('name', (0, utils_1.rewriteExpression)((0, compiler_core_1.createSimpleExpression)(`"${name}-"+` + slotKey), context)
.content);
// 存储原始的 slot 名称
dir.slotName = name;
return dir;
}
function parseVForKeyAlias(context) {
let { currentScope } = context;
const keys = [];
while (currentScope) {
if ((0, transform_1.isVForScope)(currentScope) && !(0, transform_1.isScopedSlotVFor)(currentScope)) {
keys.push(currentScope.keyAlias);
}
currentScope = currentScope.parent;
}
return keys;
}
function parseVForIndexes(context) {
let { currentScope } = context;
const indexes = [];
while (currentScope) {
if ((0, transform_1.isVForScope)(currentScope) && !(0, transform_1.isScopedSlotVFor)(currentScope)) {
indexes.push(currentScope.indexAlias);
}
currentScope = currentScope.parent;
}
return indexes;
}
function parseSlotKeyByVForIndexes(indexes) {
return indexes.reverse().join(`+'-'+`);
}
function parseScopedSlotKey(context) {
const indexes = parseVForIndexes(context);
const inFor = !!indexes.length;
if (inFor) {
return parseSlotKeyByVForIndexes(indexes);
}
}
function transformProperty(dir, _) {
if ((0, uni_cli_shared_1.isDirectiveNode)(dir)) {
if (!dir.arg || !dir.exp) {
return;
}
const isStaticArg = dir.arg.type === 4 /* NodeTypes.SIMPLE_EXPRESSION */ && dir.arg.isStatic;
if (isStaticArg) {
return `${dir.arg.content}:${(0, codegen_1.genExpr)(dir.exp)}`;
}
return `[${(0, codegen_1.genExpr)(dir.arg)}||'']:${(0, codegen_1.genExpr)(dir.exp)}`;
}
if (dir.value) {
return `${dir.name}:${(0, codegen_1.genExpr)(dir.value)}`;
}
}