diff --git a/docs/rules/no-deprecated-router-link-tag-prop.md b/docs/rules/no-deprecated-router-link-tag-prop.md
index c57d05db8..e00cd8a67 100644
--- a/docs/rules/no-deprecated-router-link-tag-prop.md
+++ b/docs/rules/no-deprecated-router-link-tag-prop.md
@@ -20,16 +20,24 @@ This rule reports deprecated the `tag` attribute on `RouterLink` elements (remov
Home
+ Home
Home
+
+ Home
+
+
Home
+ Home
Home
+ Home
Home
+ Home
```
@@ -40,11 +48,16 @@ This rule reports deprecated the `tag` attribute on `RouterLink` elements (remov
```json
{
"vue/no-deprecated-router-link-tag-prop": ["error", {
- "components": ['RouterLink', 'NuxtLink']
+ "components": ['RouterLink']
}]
}
```
+- `components` (`string[]`) ... Component names which will be checked with the `tag` attribute. default `['RouterLink']`.
+
+Note: this rule will check both `CamelCase` and `PascalCase` versions of the
+given component names.
+
### `{ "components": ['RouterLink', 'NuxtLink'] }`
@@ -52,11 +65,17 @@ This rule reports deprecated the `tag` attribute on `RouterLink` elements (remov
```vue
- Home
- Home
-
Home
+ Home
+
Home
+ Home
+
+ Home
+ Home
+
+ Home
+ Home
```
diff --git a/lib/rules/no-deprecated-router-link-tag-prop.js b/lib/rules/no-deprecated-router-link-tag-prop.js
index d9d1a2ee4..d73cf0ceb 100644
--- a/lib/rules/no-deprecated-router-link-tag-prop.js
+++ b/lib/rules/no-deprecated-router-link-tag-prop.js
@@ -9,6 +9,26 @@
// ------------------------------------------------------------------------------
const utils = require('../utils')
+const casing = require('../utils/casing')
+
+// --------------------------------------------------------------------------
+// Helpers
+// --------------------------------------------------------------------------
+
+/** @param {RuleContext} context */
+function getComponentNames(context) {
+ let components = ['RouterLink']
+
+ if (context.options[0] && context.options[0].components) {
+ components = context.options[0].components
+ }
+
+ return components.reduce((prev, curr) => {
+ prev.add(casing.kebabCase(curr))
+ prev.add(casing.pascalCase(curr))
+ return prev
+ }, new Set())
+}
// ------------------------------------------------------------------------------
// Rule Definition
@@ -46,39 +66,37 @@ module.exports = {
},
/** @param {RuleContext} context */
create(context) {
- let components = ['RouterLink']
- if (context.options[0] && context.options[0].components) {
- components = context.options[0].components
- }
+ const components = getComponentNames(context)
return utils.defineTemplateBodyVisitor(context, {
VElement(node) {
- if (!components.includes(node.rawName)) return
+ if (!components.has(node.rawName)) return
- const attributes = node.startTag.attributes
- attributes.forEach((attr) => {
- /** @type VIdentifier | null */
- let tagAttr = null
+ /** @type VIdentifier | null */
+ let tagKey = null
- if (attr.key.type === 'VIdentifier') {
- tagAttr = attr.key
- } else if (attr.directive && attr.key.type === 'VDirectiveKey') {
- const arg = attr.key.argument
+ const tagAttr = utils.getAttribute(node, 'tag')
+ if (tagAttr) {
+ tagKey = tagAttr.key
+ } else {
+ const directive = utils.getDirective(node, 'bind', 'tag')
+ if (directive) {
+ const arg = directive.key.argument
if (arg && arg.type === 'VIdentifier') {
- tagAttr = arg
+ tagKey = arg
}
}
+ }
- if (tagAttr && tagAttr.name === 'tag') {
- context.report({
- node: tagAttr,
- messageId: 'deprecated',
- data: {
- element: node.rawName
- }
- })
- }
- })
+ if (tagKey) {
+ context.report({
+ node: tagKey,
+ messageId: 'deprecated',
+ data: {
+ element: node.rawName
+ }
+ })
+ }
}
})
}
diff --git a/tests/lib/rules/no-deprecated-router-link-tag-prop.js b/tests/lib/rules/no-deprecated-router-link-tag-prop.js
index 6e61cd862..9154cf31c 100644
--- a/tests/lib/rules/no-deprecated-router-link-tag-prop.js
+++ b/tests/lib/rules/no-deprecated-router-link-tag-prop.js
@@ -25,6 +25,14 @@ tester.run('no-deprecated-router-link-tag-prop', rule, {
`
},
+ {
+ filename: 'test.vue',
+ code: `
+
+ Home
+
+ `
+ },
{
filename: 'test.vue',
code: `
@@ -35,6 +43,16 @@ tester.run('no-deprecated-router-link-tag-prop', rule, {
`
},
+ {
+ filename: 'test.vue',
+ code: `
+
+
+ Home
+
+
+ `
+ },
{
filename: 'test.vue',
code: `
@@ -43,6 +61,14 @@ tester.run('no-deprecated-router-link-tag-prop', rule, {
`
},
+ {
+ filename: 'test.vue',
+ code: `
+
+ Home
+
+ `
+ },
{
filename: 'test.vue',
code: `
@@ -52,6 +78,16 @@ tester.run('no-deprecated-router-link-tag-prop', rule, {
`
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+
+ Home
+
+
+ `
}
],
invalid: [
@@ -71,6 +107,22 @@ tester.run('no-deprecated-router-link-tag-prop', rule, {
}
]
},
+ {
+ filename: 'test.vue',
+ code: `
+
+ Home
+
+ `,
+ errors: [
+ {
+ message:
+ "'tag' property on 'router-link' component is deprecated. Use scoped slots instead.",
+ line: 3,
+ column: 22
+ }
+ ]
+ },
{
filename: 'test.vue',
code: `
@@ -88,6 +140,40 @@ tester.run('no-deprecated-router-link-tag-prop', rule, {
}
]
},
+ {
+ filename: 'test.vue',
+ code: `
+
+ Home
+
+ `,
+ options: [{ components: ['router-link'] }],
+ errors: [
+ {
+ message:
+ "'tag' property on 'RouterLink' component is deprecated. Use scoped slots instead.",
+ line: 3,
+ column: 21
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ Home
+
+ `,
+ options: [{ components: ['RouterLink'] }],
+ errors: [
+ {
+ message:
+ "'tag' property on 'router-link' component is deprecated. Use scoped slots instead.",
+ line: 3,
+ column: 22
+ }
+ ]
+ },
{
filename: 'test.vue',
code: `
@@ -104,6 +190,22 @@ tester.run('no-deprecated-router-link-tag-prop', rule, {
}
]
},
+ {
+ filename: 'test.vue',
+ code: `
+
+ Home
+
+ `,
+ errors: [
+ {
+ message:
+ "'tag' property on 'router-link' component is deprecated. Use scoped slots instead.",
+ line: 3,
+ column: 23
+ }
+ ]
+ },
{
filename: 'test.vue',
code: `
@@ -121,6 +223,23 @@ tester.run('no-deprecated-router-link-tag-prop', rule, {
}
]
},
+ {
+ filename: 'test.vue',
+ code: `
+
+ Home
+
+ `,
+ options: [{ components: ['RouterLink'] }],
+ errors: [
+ {
+ message:
+ "'tag' property on 'router-link' component is deprecated. Use scoped slots instead.",
+ line: 3,
+ column: 23
+ }
+ ]
+ },
{
filename: 'test.vue',
code: `
@@ -138,6 +257,23 @@ tester.run('no-deprecated-router-link-tag-prop', rule, {
}
]
},
+ {
+ filename: 'test.vue',
+ code: `
+
+ Home
+
+ `,
+ options: [{ components: ['NuxtLink'] }],
+ errors: [
+ {
+ message:
+ "'tag' property on 'nuxt-link' component is deprecated. Use scoped slots instead.",
+ line: 3,
+ column: 20
+ }
+ ]
+ },
{
filename: 'test.vue',
code: `
@@ -154,6 +290,23 @@ tester.run('no-deprecated-router-link-tag-prop', rule, {
column: 20
}
]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ Home
+
+ `,
+ options: [{ components: ['NuxtLink'] }],
+ errors: [
+ {
+ message:
+ "'tag' property on 'nuxt-link' component is deprecated. Use scoped slots instead.",
+ line: 3,
+ column: 21
+ }
+ ]
}
]
})