@@ -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+
3853module . 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 ) {
@@ -139,32 +167,26 @@ module.exports = {
139167 utils . defineTemplateBodyVisitor ( context , {
140168 /** @param {VElement } node */
141169 "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 )
150171
151- /** @type {string | undefined } */
152- let slotName
172+ // if no slot name is declared, default to 'default'
153173 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' )
158175 return
159- } else {
160- slotName = nameNode . value ?. value
161176 }
162177
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 )
168190 }
169191 }
170192 } )
0 commit comments