@@ -35,6 +35,21 @@ function getSlotsName(node) {
35
35
return null
36
36
}
37
37
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
+
38
53
module . exports = {
39
54
meta : {
40
55
type : 'problem' ,
@@ -68,6 +83,19 @@ module.exports = {
68
83
}
69
84
const slotsDefined = new Set ( )
70
85
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
+
71
99
return utils . compositingVisitors (
72
100
utils . defineScriptSetupVisitor ( context , {
73
101
onDefineSlotsEnter ( node ) {
@@ -139,32 +167,26 @@ module.exports = {
139
167
utils . defineTemplateBodyVisitor ( context , {
140
168
/** @param {VElement } node */
141
169
"VElement[name='slot']" ( node ) {
142
- const nameNode = node . startTag . attributes . find (
143
- ( node ) =>
144
- ( ! node . directive && node . key . name === 'name' ) ||
145
- ( node . directive &&
146
- node . key . name . name === 'bind' &&
147
- node . key . argument ?. type === 'VIdentifier' &&
148
- node . key . argument ?. name === 'name' )
149
- )
170
+ const nameNode = getSlotNameNode ( node )
150
171
151
- /** @type {string | undefined } */
152
- let slotName
172
+ // if no slot name is declared, default to 'default'
153
173
if ( ! nameNode ) {
154
- // If no slot name is declared, default to 'default'
155
- slotName = 'default'
156
- } else if ( nameNode . directive ) {
157
- // ignore attribute binding
174
+ reportMissingSlot ( node , 'default' )
158
175
return
159
- } else {
160
- slotName = nameNode . value ?. value
161
176
}
162
177
163
- if ( ! slotsDefined . has ( slotName ) ) {
164
- context . report ( {
165
- node,
166
- messageId : 'requireExplicitSlots'
167
- } )
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
+ // check and report if slot name is declared or is undefined
189
+ reportMissingSlot ( node , nameNode . value ?. value )
168
190
}
169
191
}
170
192
} )
0 commit comments