Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e13089e

Browse files
authored
fix(require-explicit-slots): ignore attribute binding (#2591)
1 parent 54a99c5 commit e13089e

File tree

2 files changed

+96
-10
lines changed

2 files changed

+96
-10
lines changed

‎lib/rules/require-explicit-slots.js

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,21 @@ function getSlotsName(node) {
3535
return null
3636
}
3737

38+
/**
39+
* @param {VElement} node
40+
* @return {VAttribute | VDirective | undefined}
41+
*/
42+
function getSlotNameNode(node) {
43+
return node.startTag.attributes.find(
44+
(node) =>
45+
(!node.directive && node.key.name === 'name') ||
46+
(node.directive &&
47+
node.key.name.name === 'bind' &&
48+
node.key.argument?.type === 'VIdentifier' &&
49+
node.key.argument?.name === 'name')
50+
)
51+
}
52+
3853
module.exports = {
3954
meta: {
4055
type: 'problem',
@@ -68,6 +83,19 @@ module.exports = {
6883
}
6984
const slotsDefined = new Set()
7085

86+
/**
87+
* @param {VElement} node
88+
* @param {string | undefined} slotName
89+
*/
90+
function reportMissingSlot(node, slotName) {
91+
if (!slotsDefined.has(slotName)) {
92+
context.report({
93+
node,
94+
messageId: 'requireExplicitSlots'
95+
})
96+
}
97+
}
98+
7199
return utils.compositingVisitors(
72100
utils.defineScriptSetupVisitor(context, {
73101
onDefineSlotsEnter(node) {
@@ -137,20 +165,27 @@ module.exports = {
137165
}
138166
}),
139167
utils.defineTemplateBodyVisitor(context, {
168+
/** @param {VElement} node */
140169
"VElement[name='slot']"(node) {
141-
let slotName = 'default'
142-
143-
const slotNameAttr = utils.getAttribute(node, 'name')
170+
const nameNode = getSlotNameNode(node)
144171

145-
if (slotNameAttr?.value) {
146-
slotName = slotNameAttr.value.value
172+
// if no slot name is declared, default to 'default'
173+
if (!nameNode) {
174+
reportMissingSlot(node, 'default')
175+
return
147176
}
148177

149-
if (!slotsDefined.has(slotName)) {
150-
context.report({
151-
node,
152-
messageId: 'requireExplicitSlots'
153-
})
178+
if (nameNode.directive) {
179+
const expression = nameNode.value?.expression
180+
// ignore attribute binding except string literal
181+
if (!expression || !utils.isStringLiteral(expression)) {
182+
return
183+
}
184+
185+
const name = utils.getStringLiteralValue(expression) || undefined
186+
reportMissingSlot(node, name)
187+
} else {
188+
reportMissingSlot(node, nameNode.value?.value)
154189
}
155190
}
156191
})

‎tests/lib/rules/require-explicit-slots.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,37 @@ tester.run('require-explicit-slots', rule, {
160160
parser: null
161161
}
162162
}
163+
},
164+
// attribute binding
165+
{
166+
filename: 'test.vue',
167+
code: `
168+
<template>
169+
<div>
170+
<slot :name="'foo'"></slot>
171+
<slot :name="\`bar\`"></slot>
172+
</div>
173+
</template>
174+
<script setup lang="ts">
175+
defineSlots<{
176+
foo(props: { msg: string }): any
177+
bar(props: { msg: string }): any
178+
}>()
179+
</script>`
180+
},
181+
{
182+
filename: 'test.vue',
183+
code: `
184+
<template>
185+
<div>
186+
<slot :name="bar"></slot>
187+
</div>
188+
</template>
189+
<script setup lang="ts">
190+
defineSlots<{
191+
default(props: { msg: string }): any
192+
}>()
193+
</script>`
163194
}
164195
],
165196
invalid: [
@@ -291,6 +322,26 @@ tester.run('require-explicit-slots', rule, {
291322
}
292323
]
293324
},
325+
{
326+
// ignore attribute binding except string literal
327+
filename: 'test.vue',
328+
code: `
329+
<template>
330+
<div>
331+
<slot :name="'foo'"></slot>
332+
</div>
333+
</template>
334+
<script setup lang="ts">
335+
defineSlots<{
336+
default(props: { msg: string }): any
337+
}>()
338+
</script>`,
339+
errors: [
340+
{
341+
message: 'Slots must be explicitly defined.'
342+
}
343+
]
344+
},
294345
{
295346
filename: 'test.vue',
296347
code: `

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /