188 lines
7.2 KiB
JavaScript
188 lines
7.2 KiB
JavaScript
"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)}`;
|
|
}
|
|
}
|