Skip to content

Commit

Permalink
feat(no-deprecated-slot-attribute): improve autofix to wrap `<templat…
Browse files Browse the repository at this point in the history
…e v-slot>` (#2390)
  • Loading branch information
privatenumber committed Feb 18, 2024
1 parent 33b67a4 commit 7bdefb2
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 15 deletions.
22 changes: 17 additions & 5 deletions lib/rules/syntaxes/slot-attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ module.exports = {
* @returns {IterableIterator<Fix>} fix data
*/
function* fixSlotToVSlot(fixer, slotAttr, slotName, vBind) {
const element = slotAttr.parent
const scopeAttr = element.attributes.find(
const startTag = slotAttr.parent
const scopeAttr = startTag.attributes.find(
(attr) =>
attr.directive === true &&
attr.key.name &&
Expand All @@ -89,9 +89,21 @@ module.exports = {
: ''

const replaceText = `v-slot${nameArgument}${scopeValue}`
yield fixer.replaceText(slotAttr || scopeAttr, replaceText)
if (slotAttr && scopeAttr) {
yield fixer.remove(scopeAttr)

const element = startTag.parent
if (element.name === 'template') {
yield fixer.replaceText(slotAttr || scopeAttr, replaceText)
if (slotAttr && scopeAttr) {
yield fixer.remove(scopeAttr)
}
} else {
yield fixer.remove(slotAttr || scopeAttr)
if (slotAttr && scopeAttr) {
yield fixer.remove(scopeAttr)
}

yield fixer.insertTextBefore(element, `<template ${replaceText}>\n`)
yield fixer.insertTextAfter(element, `\n</template>`)
}
}
/**
Expand Down
14 changes: 12 additions & 2 deletions lib/rules/syntaxes/slot-scope-attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,26 @@ module.exports = {
* Convert to `v-slot`.
* @param {RuleFixer} fixer fixer
* @param {VDirective} scopeAttr node of `slot-scope`
* @returns {Fix} fix data
* @returns {Fix[]} fix data
*/
function fixSlotScopeToVSlot(fixer, scopeAttr) {
const element = scopeAttr.parent.parent
const scopeValue =
scopeAttr && scopeAttr.value
? `=${sourceCode.getText(scopeAttr.value)}`
: ''

const replaceText = `v-slot${scopeValue}`
return fixer.replaceText(scopeAttr, replaceText)
if (element.name === 'template') {
return [fixer.replaceText(scopeAttr, replaceText)]
} else {
const tokenBefore = tokenStore.getTokenBefore(scopeAttr)
return [
fixer.removeRange([tokenBefore.range[1], scopeAttr.range[1]]),
fixer.insertTextBefore(element, `<template ${replaceText}>\n`),
fixer.insertTextAfter(element, `\n</template>`)
]
}
}
/**
* Reports `slot-scope` node
Expand Down
3 changes: 0 additions & 3 deletions lib/rules/syntaxes/utils/can-convert-to-v-slot.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ const utils = require('../../../utils')
* @param {ParserServices.TokenStore} tokenStore
*/
module.exports = function canConvertToVSlot(element, sourceCode, tokenStore) {
if (element.name !== 'template') {
return false
}
const ownerElement = element.parent
if (
ownerElement.type === 'VDocumentFragment' ||
Expand Down
26 changes: 23 additions & 3 deletions tests/lib/rules/no-deprecated-slot-attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,12 @@ tester.run('no-deprecated-slot-attribute', rule, {
<a slot="name" />
</LinkList>
</template>`,
output: null,
output: `
<template>
<LinkList>
<template v-slot:name>\n<a />\n</template>
</LinkList>
</template>`,
errors: [
{
message: '`slot` attributes are deprecated.',
Expand All @@ -350,7 +355,12 @@ tester.run('no-deprecated-slot-attribute', rule, {
<a :slot="name" />
</LinkList>
</template>`,
output: null,
output: `
<template>
<LinkList>
<template v-slot:[name]>\n<a />\n</template>
</LinkList>
</template>`,
errors: [
{
message: '`slot` attributes are deprecated.',
Expand Down Expand Up @@ -616,7 +626,17 @@ tester.run('no-deprecated-slot-attribute', rule, {
</two>
</my-component>
</template>`,
output: null,
output: `
<template>
<my-component>
<one slot="one">
A
</one>
<template v-slot:two>\n<two >
B
</two>\n</template>
</my-component>
</template>`,
options: [
{
ignore: ['one']
Expand Down
8 changes: 6 additions & 2 deletions tests/lib/rules/no-deprecated-slot-scope-attribute.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,19 @@ tester.run('no-deprecated-slot-scope-attribute', rule, {
}
]
},
// cannot fix
{
code: `
<template>
<LinkList>
<a slot-scope="{a}" />
</LinkList>
</template>`,
output: null,
output: `
<template>
<LinkList>
<template v-slot="{a}">\n<a />\n</template>
</LinkList>
</template>`,
errors: [
{
message: '`slot-scope` are deprecated.',
Expand Down

0 comments on commit 7bdefb2

Please sign in to comment.