diff --git a/docs/rules/attribute-hyphenation.md b/docs/rules/attribute-hyphenation.md
index d5fba2e31..89442fceb 100644
--- a/docs/rules/attribute-hyphenation.md
+++ b/docs/rules/attribute-hyphenation.md
@@ -36,7 +36,8 @@ This rule enforces using hyphenated attribute names on custom components in Vue
```json
{
"vue/attribute-hyphenation": ["error", "always" | "never", {
- "ignore": []
+ "ignore": [],
+ "ignoreTags": []
}]
}
```
@@ -44,9 +45,10 @@ This rule enforces using hyphenated attribute names on custom components in Vue
Default casing is set to `always`. By default the following attributes are ignored: `data-`, `aria-`, `slot-scope`,
and all the [SVG attributes](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute) with either an upper case letter or an hyphen.
-- `"always"` (default) ... Use hyphenated name.
-- `"never"` ... Don't use hyphenated name except the ones that are ignored.
-- `"ignore"` ... Array of ignored names
+- `"always"` (default) ... Use hyphenated attribute name.
+- `"never"` ... Don't use hyphenated attribute name.
+- `"ignore"` ... Array of attribute names that don't need to follow the specified casing.
+- `"ignoreTags"` ... Array of tag names whose attributes don't need to follow the specified casing.
### `"always"`
@@ -109,6 +111,22 @@ Don't use hyphenated name but allow custom attributes
+### `"never", { "ignoreTags": ["/^custom-/"] }`
+
+
+
+```vue
+
+
+
+
+
+
+
+```
+
+
+
## :couple: Related Rules
- [vue/v-on-event-hyphenation](./v-on-event-hyphenation.md)
diff --git a/docs/rules/v-on-event-hyphenation.md b/docs/rules/v-on-event-hyphenation.md
index 811b37437..493a9dac9 100644
--- a/docs/rules/v-on-event-hyphenation.md
+++ b/docs/rules/v-on-event-hyphenation.md
@@ -39,14 +39,16 @@ This rule enforces using hyphenated v-on event names on custom components in Vue
{
"vue/v-on-event-hyphenation": ["error", "always" | "never", {
"autofix": false,
- "ignore": []
+ "ignore": [],
+ "ignoreTags": []
}]
}
```
-- `"always"` (default) ... Use hyphenated name.
-- `"never"` ... Don't use hyphenated name.
-- `"ignore"` ... Array of ignored names
+- `"always"` (default) ... Use hyphenated event name.
+- `"never"` ... Don't use hyphenated event name.
+- `"ignore"` ... Array of event names that don't need to follow the specified casing.
+- `"ignoreTags"` ... Array of tag names whose events don't need to follow the specified casing.
- `"autofix"` ... If `true`, enable autofix. If you are using Vue 2, we recommend that you do not use it due to its side effects.
### `"always"`
@@ -104,6 +106,22 @@ Don't use hyphenated name but allow custom event names
+### `"never", { "ignoreTags": ["/^custom-/"] }`
+
+
+
+```vue
+
+
+
+
+
+
+
+```
+
+
+
## :couple: Related Rules
- [vue/custom-event-name-casing](./custom-event-name-casing.md)
diff --git a/lib/rules/attribute-hyphenation.js b/lib/rules/attribute-hyphenation.js
index 35519d231..65d096cd4 100644
--- a/lib/rules/attribute-hyphenation.js
+++ b/lib/rules/attribute-hyphenation.js
@@ -6,6 +6,7 @@
const utils = require('../utils')
const casing = require('../utils/casing')
+const { toRegExp } = require('../utils/regexp')
const svgAttributes = require('../utils/svg-attributes-weird-case.json')
/**
@@ -56,6 +57,12 @@ module.exports = {
},
uniqueItems: true,
additionalItems: false
+ },
+ ignoreTags: {
+ type: 'array',
+ items: { type: 'string' },
+ uniqueItems: true,
+ additionalItems: false
}
},
additionalProperties: false
@@ -72,6 +79,11 @@ module.exports = {
const option = context.options[0]
const optionsPayload = context.options[1]
const useHyphenated = option !== 'never'
+ /** @type {RegExp[]} */
+ const ignoredTagsRegexps = (
+ (optionsPayload && optionsPayload.ignoreTags) ||
+ []
+ ).map(toRegExp)
const ignoredAttributes = ['data-', 'aria-', 'slot-scope', ...svgAttributes]
if (optionsPayload && optionsPayload.ignore) {
@@ -130,11 +142,17 @@ module.exports = {
return useHyphenated ? value.toLowerCase() === value : !/-/.test(value)
}
+ /** @param {string} name */
+ function isIgnoredTagName(name) {
+ return ignoredTagsRegexps.some((re) => re.test(name))
+ }
+
return utils.defineTemplateBodyVisitor(context, {
VAttribute(node) {
+ const element = node.parent.parent
if (
- !utils.isCustomComponent(node.parent.parent) &&
- node.parent.parent.name !== 'slot'
+ (!utils.isCustomComponent(element) && element.name !== 'slot') ||
+ isIgnoredTagName(element.rawName)
)
return
diff --git a/lib/rules/v-on-event-hyphenation.js b/lib/rules/v-on-event-hyphenation.js
index f99a45fdc..c9fac76e8 100644
--- a/lib/rules/v-on-event-hyphenation.js
+++ b/lib/rules/v-on-event-hyphenation.js
@@ -2,6 +2,7 @@
const utils = require('../utils')
const casing = require('../utils/casing')
+const { toRegExp } = require('../utils/regexp')
module.exports = {
meta: {
@@ -35,6 +36,12 @@ module.exports = {
},
uniqueItems: true,
additionalItems: false
+ },
+ ignoreTags: {
+ type: 'array',
+ items: { type: 'string' },
+ uniqueItems: true,
+ additionalItems: false
}
},
additionalProperties: false
@@ -56,6 +63,11 @@ module.exports = {
const useHyphenated = option !== 'never'
/** @type {string[]} */
const ignoredAttributes = (optionsPayload && optionsPayload.ignore) || []
+ /** @type {RegExp[]} */
+ const ignoredTagsRegexps = (
+ (optionsPayload && optionsPayload.ignoreTags) ||
+ []
+ ).map(toRegExp)
const autofix = Boolean(optionsPayload && optionsPayload.autofix)
const caseConverter = casing.getConverter(
@@ -99,9 +111,20 @@ module.exports = {
return useHyphenated ? value.toLowerCase() === value : !/-/.test(value)
}
+ /** @param {string} name */
+ function isIgnoredTagName(name) {
+ return ignoredTagsRegexps.some((re) => re.test(name))
+ }
+
return utils.defineTemplateBodyVisitor(context, {
"VAttribute[directive=true][key.name.name='on']"(node) {
- if (!utils.isCustomComponent(node.parent.parent)) return
+ const element = node.parent.parent
+ if (
+ !utils.isCustomComponent(element) ||
+ isIgnoredTagName(element.rawName)
+ ) {
+ return
+ }
if (!node.key.argument || node.key.argument.type !== 'VIdentifier') {
return
}
diff --git a/tests/lib/rules/attribute-hyphenation.js b/tests/lib/rules/attribute-hyphenation.js
index 18d60e19c..738d59ae9 100644
--- a/tests/lib/rules/attribute-hyphenation.js
+++ b/tests/lib/rules/attribute-hyphenation.js
@@ -85,6 +85,26 @@ ruleTester.run('attribute-hyphenation', rule, {
filename: 'test.vue',
code: '
',
options: ['never']
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+
+
+
+ `,
+ options: ['never', { ignoreTags: ['VueComponent', '/^custom-/'] }]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+
+
+
+ `,
+ options: ['always', { ignoreTags: ['VueComponent', '/^custom-/'] }]
}
],
@@ -450,6 +470,52 @@ ruleTester.run('attribute-hyphenation', rule, {
line: 1
}
]
+ },
+ {
+ code: `
+
+
+
+
+ `,
+ output: `
+
+
+
+
+ `,
+ options: ['never', { ignoreTags: ['CustomComponent'] }],
+ errors: [
+ {
+ message: "Attribute 'my-prop' can't be hyphenated.",
+ type: 'VIdentifier',
+ line: 3,
+ column: 17
+ }
+ ]
+ },
+ {
+ code: `
+
+
+
+
+ `,
+ output: `
+
+
+
+
+ `,
+ options: ['always', { ignoreTags: ['CustomComponent'] }],
+ errors: [
+ {
+ message: "Attribute 'myProp' must be hyphenated.",
+ type: 'VIdentifier',
+ line: 3,
+ column: 17
+ }
+ ]
}
]
})
diff --git a/tests/lib/rules/v-on-event-hyphenation.js b/tests/lib/rules/v-on-event-hyphenation.js
index 54d2ec435..3f58ce1f0 100644
--- a/tests/lib/rules/v-on-event-hyphenation.js
+++ b/tests/lib/rules/v-on-event-hyphenation.js
@@ -44,6 +44,32 @@ tester.run('v-on-event-hyphenation', rule, {
`,
options: ['never', { ignore: ['custom'] }]
+ },
+ {
+ code: `
+
+
+
+ `,
+ options: ['never', { ignore: ['custom-event'] }]
+ },
+ {
+ code: `
+
+
+
+
+ `,
+ options: ['never', { ignoreTags: ['/^Vue/', 'custom-component'] }]
+ },
+ {
+ code: `
+
+
+
+
+ `,
+ options: ['always', { ignoreTags: ['/^Vue/', 'custom-component'] }]
}
],
invalid: [
@@ -179,6 +205,50 @@ tester.run('v-on-event-hyphenation', rule, {
"v-on event '@upDate:model-value' can't be hyphenated.",
"v-on event '@up-date:model-value' can't be hyphenated."
]
+ },
+ {
+ code: `
+
+
+
+
+ `,
+ output: `
+
+
+
+
+ `,
+ options: ['never', { autofix: true, ignoreTags: ['CustomComponent'] }],
+ errors: [
+ {
+ message: "v-on event 'v-on:custom-event' can't be hyphenated.",
+ line: 3,
+ column: 23
+ }
+ ]
+ },
+ {
+ code: `
+
+
+
+
+ `,
+ output: `
+
+
+
+
+ `,
+ options: ['always', { autofix: true, ignoreTags: ['CustomComponent'] }],
+ errors: [
+ {
+ message: "v-on event 'v-on:customEvent' must be hyphenated.",
+ line: 3,
+ column: 23
+ }
+ ]
}
]
})