diff --git a/lib/rules/require-explicit-slots.js b/lib/rules/require-explicit-slots.js
index 0ae77b597..f87503bb7 100644
--- a/lib/rules/require-explicit-slots.js
+++ b/lib/rules/require-explicit-slots.js
@@ -35,6 +35,21 @@ function getSlotsName(node) {
return null
}
+/**
+ * @param {VElement} node
+ * @return {VAttribute | VDirective | undefined}
+ */
+function getSlotNameNode(node) {
+ return node.startTag.attributes.find(
+ (node) =>
+ (!node.directive && node.key.name === 'name') ||
+ (node.directive &&
+ node.key.name.name === 'bind' &&
+ node.key.argument?.type === 'VIdentifier' &&
+ node.key.argument?.name === 'name')
+ )
+}
+
module.exports = {
meta: {
type: 'problem',
@@ -68,6 +83,19 @@ module.exports = {
}
const slotsDefined = new Set()
+ /**
+ * @param {VElement} node
+ * @param {string | undefined} slotName
+ */
+ function reportMissingSlot(node, slotName) {
+ if (!slotsDefined.has(slotName)) {
+ context.report({
+ node,
+ messageId: 'requireExplicitSlots'
+ })
+ }
+ }
+
return utils.compositingVisitors(
utils.defineScriptSetupVisitor(context, {
onDefineSlotsEnter(node) {
@@ -137,20 +165,27 @@ module.exports = {
}
}),
utils.defineTemplateBodyVisitor(context, {
+ /** @param {VElement} node */
"VElement[name='slot']"(node) {
- let slotName = 'default'
-
- const slotNameAttr = utils.getAttribute(node, 'name')
+ const nameNode = getSlotNameNode(node)
- if (slotNameAttr?.value) {
- slotName = slotNameAttr.value.value
+ // if no slot name is declared, default to 'default'
+ if (!nameNode) {
+ reportMissingSlot(node, 'default')
+ return
}
- if (!slotsDefined.has(slotName)) {
- context.report({
- node,
- messageId: 'requireExplicitSlots'
- })
+ if (nameNode.directive) {
+ const expression = nameNode.value?.expression
+ // ignore attribute binding except string literal
+ if (!expression || !utils.isStringLiteral(expression)) {
+ return
+ }
+
+ const name = utils.getStringLiteralValue(expression) || undefined
+ reportMissingSlot(node, name)
+ } else {
+ reportMissingSlot(node, nameNode.value?.value)
}
}
})
diff --git a/tests/lib/rules/require-explicit-slots.js b/tests/lib/rules/require-explicit-slots.js
index ebbc28818..92d1a1334 100644
--- a/tests/lib/rules/require-explicit-slots.js
+++ b/tests/lib/rules/require-explicit-slots.js
@@ -160,6 +160,37 @@ tester.run('require-explicit-slots', rule, {
parser: null
}
}
+ },
+ // attribute binding
+ {
+ filename: 'test.vue',
+ code: `
+
+
+
+
+
+
+ `
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+
+
+
+
+ `
}
],
invalid: [
@@ -291,6 +322,26 @@ tester.run('require-explicit-slots', rule, {
}
]
},
+ {
+ // ignore attribute binding except string literal
+ filename: 'test.vue',
+ code: `
+
+
+
+
+
+ `,
+ errors: [
+ {
+ message: 'Slots must be explicitly defined.'
+ }
+ ]
+ },
{
filename: 'test.vue',
code: `