Skip to content

Commit 7bdefb2

Browse files
feat(no-deprecated-slot-attribute): improve autofix to wrap <template v-slot> (#2390)
1 parent 33b67a4 commit 7bdefb2

File tree

5 files changed

+58
-15
lines changed

5 files changed

+58
-15
lines changed

lib/rules/syntaxes/slot-attribute.js

+17-5
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ module.exports = {
7171
* @returns {IterableIterator<Fix>} fix data
7272
*/
7373
function* fixSlotToVSlot(fixer, slotAttr, slotName, vBind) {
74-
const element = slotAttr.parent
75-
const scopeAttr = element.attributes.find(
74+
const startTag = slotAttr.parent
75+
const scopeAttr = startTag.attributes.find(
7676
(attr) =>
7777
attr.directive === true &&
7878
attr.key.name &&
@@ -89,9 +89,21 @@ module.exports = {
8989
: ''
9090

9191
const replaceText = `v-slot${nameArgument}${scopeValue}`
92-
yield fixer.replaceText(slotAttr || scopeAttr, replaceText)
93-
if (slotAttr && scopeAttr) {
94-
yield fixer.remove(scopeAttr)
92+
93+
const element = startTag.parent
94+
if (element.name === 'template') {
95+
yield fixer.replaceText(slotAttr || scopeAttr, replaceText)
96+
if (slotAttr && scopeAttr) {
97+
yield fixer.remove(scopeAttr)
98+
}
99+
} else {
100+
yield fixer.remove(slotAttr || scopeAttr)
101+
if (slotAttr && scopeAttr) {
102+
yield fixer.remove(scopeAttr)
103+
}
104+
105+
yield fixer.insertTextBefore(element, `<template ${replaceText}>\n`)
106+
yield fixer.insertTextAfter(element, `\n</template>`)
95107
}
96108
}
97109
/**

lib/rules/syntaxes/slot-scope-attribute.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,26 @@ module.exports = {
6262
* Convert to `v-slot`.
6363
* @param {RuleFixer} fixer fixer
6464
* @param {VDirective} scopeAttr node of `slot-scope`
65-
* @returns {Fix} fix data
65+
* @returns {Fix[]} fix data
6666
*/
6767
function fixSlotScopeToVSlot(fixer, scopeAttr) {
68+
const element = scopeAttr.parent.parent
6869
const scopeValue =
6970
scopeAttr && scopeAttr.value
7071
? `=${sourceCode.getText(scopeAttr.value)}`
7172
: ''
7273

7374
const replaceText = `v-slot${scopeValue}`
74-
return fixer.replaceText(scopeAttr, replaceText)
75+
if (element.name === 'template') {
76+
return [fixer.replaceText(scopeAttr, replaceText)]
77+
} else {
78+
const tokenBefore = tokenStore.getTokenBefore(scopeAttr)
79+
return [
80+
fixer.removeRange([tokenBefore.range[1], scopeAttr.range[1]]),
81+
fixer.insertTextBefore(element, `<template ${replaceText}>\n`),
82+
fixer.insertTextAfter(element, `\n</template>`)
83+
]
84+
}
7585
}
7686
/**
7787
* Reports `slot-scope` node

lib/rules/syntaxes/utils/can-convert-to-v-slot.js

-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ const utils = require('../../../utils')
2525
* @param {ParserServices.TokenStore} tokenStore
2626
*/
2727
module.exports = function canConvertToVSlot(element, sourceCode, tokenStore) {
28-
if (element.name !== 'template') {
29-
return false
30-
}
3128
const ownerElement = element.parent
3229
if (
3330
ownerElement.type === 'VDocumentFragment' ||

tests/lib/rules/no-deprecated-slot-attribute.js

+23-3
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,12 @@ tester.run('no-deprecated-slot-attribute', rule, {
335335
<a slot="name" />
336336
</LinkList>
337337
</template>`,
338-
output: null,
338+
output: `
339+
<template>
340+
<LinkList>
341+
<template v-slot:name>\n<a />\n</template>
342+
</LinkList>
343+
</template>`,
339344
errors: [
340345
{
341346
message: '`slot` attributes are deprecated.',
@@ -350,7 +355,12 @@ tester.run('no-deprecated-slot-attribute', rule, {
350355
<a :slot="name" />
351356
</LinkList>
352357
</template>`,
353-
output: null,
358+
output: `
359+
<template>
360+
<LinkList>
361+
<template v-slot:[name]>\n<a />\n</template>
362+
</LinkList>
363+
</template>`,
354364
errors: [
355365
{
356366
message: '`slot` attributes are deprecated.',
@@ -616,7 +626,17 @@ tester.run('no-deprecated-slot-attribute', rule, {
616626
</two>
617627
</my-component>
618628
</template>`,
619-
output: null,
629+
output: `
630+
<template>
631+
<my-component>
632+
<one slot="one">
633+
A
634+
</one>
635+
<template v-slot:two>\n<two >
636+
B
637+
</two>\n</template>
638+
</my-component>
639+
</template>`,
620640
options: [
621641
{
622642
ignore: ['one']

tests/lib/rules/no-deprecated-slot-scope-attribute.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,19 @@ tester.run('no-deprecated-slot-scope-attribute', rule, {
9090
}
9191
]
9292
},
93-
// cannot fix
9493
{
9594
code: `
9695
<template>
9796
<LinkList>
9897
<a slot-scope="{a}" />
9998
</LinkList>
10099
</template>`,
101-
output: null,
100+
output: `
101+
<template>
102+
<LinkList>
103+
<template v-slot="{a}">\n<a />\n</template>
104+
</LinkList>
105+
</template>`,
102106
errors: [
103107
{
104108
message: '`slot-scope` are deprecated.',

0 commit comments

Comments
 (0)