Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9ddf3e5

Browse filesBrowse files
waynzhFloEdelmann
andauthored
feat: add ignoreTags option (#2609)
Co-authored-by: Flo Edelmann <git@flo-edelmann.de>
1 parent bea53c0 commit 9ddf3e5
Copy full SHA for 9ddf3e5

File tree

Expand file treeCollapse file tree

6 files changed

+224
-11
lines changed
Filter options
Expand file treeCollapse file tree

6 files changed

+224
-11
lines changed

‎docs/rules/attribute-hyphenation.md

Copy file name to clipboardExpand all lines: docs/rules/attribute-hyphenation.md
+22-4Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,19 @@ This rule enforces using hyphenated attribute names on custom components in Vue
3636
```json
3737
{
3838
"vue/attribute-hyphenation": ["error", "always" | "never", {
39-
"ignore": []
39+
"ignore": [],
40+
"ignoreTags": []
4041
}]
4142
}
4243
```
4344

4445
Default casing is set to `always`. By default the following attributes are ignored: `data-`, `aria-`, `slot-scope`,
4546
and all the [SVG attributes](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute) with either an upper case letter or an hyphen.
4647

47-
- `"always"` (default) ... Use hyphenated name.
48-
- `"never"` ... Don't use hyphenated name except the ones that are ignored.
49-
- `"ignore"` ... Array of ignored names
48+
- `"always"` (default) ... Use hyphenated attribute name.
49+
- `"never"` ... Don't use hyphenated attribute name.
50+
- `"ignore"` ... Array of attribute names that don't need to follow the specified casing.
51+
- `"ignoreTags"` ... Array of tag names whose attributes don't need to follow the specified casing.
5052

5153
### `"always"`
5254

@@ -109,6 +111,22 @@ Don't use hyphenated name but allow custom attributes
109111

110112
</eslint-code-block>
111113

114+
### `"never", { "ignoreTags": ["/^custom-/"] }`
115+
116+
<eslint-code-block fix :rules="{'vue/attribute-hyphenation': ['error', 'never', { ignoreTags: ['/^custom-/'] }]}">
117+
118+
```vue
119+
<template>
120+
<!-- ✓ GOOD -->
121+
<custom-component my-prop="prop" />
122+
123+
<!-- ✗ BAD -->
124+
<my-component my-prop="prop" />
125+
</template>
126+
```
127+
128+
</eslint-code-block>
129+
112130
## :couple: Related Rules
113131

114132
- [vue/v-on-event-hyphenation](./v-on-event-hyphenation.md)

‎docs/rules/v-on-event-hyphenation.md

Copy file name to clipboardExpand all lines: docs/rules/v-on-event-hyphenation.md
+22-4Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,16 @@ This rule enforces using hyphenated v-on event names on custom components in Vue
3939
{
4040
"vue/v-on-event-hyphenation": ["error", "always" | "never", {
4141
"autofix": false,
42-
"ignore": []
42+
"ignore": [],
43+
"ignoreTags": []
4344
}]
4445
}
4546
```
4647

47-
- `"always"` (default) ... Use hyphenated name.
48-
- `"never"` ... Don't use hyphenated name.
49-
- `"ignore"` ... Array of ignored names
48+
- `"always"` (default) ... Use hyphenated event name.
49+
- `"never"` ... Don't use hyphenated event name.
50+
- `"ignore"` ... Array of event names that don't need to follow the specified casing.
51+
- `"ignoreTags"` ... Array of tag names whose events don't need to follow the specified casing.
5052
- `"autofix"` ... If `true`, enable autofix. If you are using Vue 2, we recommend that you do not use it due to its side effects.
5153

5254
### `"always"`
@@ -104,6 +106,22 @@ Don't use hyphenated name but allow custom event names
104106

105107
</eslint-code-block>
106108

109+
### `"never", { "ignoreTags": ["/^custom-/"] }`
110+
111+
<eslint-code-block fix :rules="{'vue/v-on-event-hyphenation': ['error', 'never', { ignoreTags: ['/^custom-/'], autofix: true }]}">
112+
113+
```vue
114+
<template>
115+
<!-- ✓ GOOD -->
116+
<custom-component v-on:my-event="handleEvent" />
117+
118+
<!-- ✗ BAD -->
119+
<my-component v-on:my-event="handleEvent" />
120+
</template>
121+
```
122+
123+
</eslint-code-block>
124+
107125
## :couple: Related Rules
108126

109127
- [vue/custom-event-name-casing](./custom-event-name-casing.md)

‎lib/rules/attribute-hyphenation.js

Copy file name to clipboardExpand all lines: lib/rules/attribute-hyphenation.js
+20-2Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
const utils = require('../utils')
88
const casing = require('../utils/casing')
9+
const { toRegExp } = require('../utils/regexp')
910
const svgAttributes = require('../utils/svg-attributes-weird-case.json')
1011

1112
/**
@@ -56,6 +57,12 @@ module.exports = {
5657
},
5758
uniqueItems: true,
5859
additionalItems: false
60+
},
61+
ignoreTags: {
62+
type: 'array',
63+
items: { type: 'string' },
64+
uniqueItems: true,
65+
additionalItems: false
5966
}
6067
},
6168
additionalProperties: false
@@ -72,6 +79,11 @@ module.exports = {
7279
const option = context.options[0]
7380
const optionsPayload = context.options[1]
7481
const useHyphenated = option !== 'never'
82+
/** @type {RegExp[]} */
83+
const ignoredTagsRegexps = (
84+
(optionsPayload && optionsPayload.ignoreTags) ||
85+
[]
86+
).map(toRegExp)
7587
const ignoredAttributes = ['data-', 'aria-', 'slot-scope', ...svgAttributes]
7688

7789
if (optionsPayload && optionsPayload.ignore) {
@@ -130,11 +142,17 @@ module.exports = {
130142
return useHyphenated ? value.toLowerCase() === value : !/-/.test(value)
131143
}
132144

145+
/** @param {string} name */
146+
function isIgnoredTagName(name) {
147+
return ignoredTagsRegexps.some((re) => re.test(name))
148+
}
149+
133150
return utils.defineTemplateBodyVisitor(context, {
134151
VAttribute(node) {
152+
const element = node.parent.parent
135153
if (
136-
!utils.isCustomComponent(node.parent.parent) &&
137-
node.parent.parent.name !== 'slot'
154+
(!utils.isCustomComponent(element) && element.name !== 'slot') ||
155+
isIgnoredTagName(element.rawName)
138156
)
139157
return
140158

‎lib/rules/v-on-event-hyphenation.js

Copy file name to clipboardExpand all lines: lib/rules/v-on-event-hyphenation.js
+24-1Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
const utils = require('../utils')
44
const casing = require('../utils/casing')
5+
const { toRegExp } = require('../utils/regexp')
56

67
module.exports = {
78
meta: {
@@ -35,6 +36,12 @@ module.exports = {
3536
},
3637
uniqueItems: true,
3738
additionalItems: false
39+
},
40+
ignoreTags: {
41+
type: 'array',
42+
items: { type: 'string' },
43+
uniqueItems: true,
44+
additionalItems: false
3845
}
3946
},
4047
additionalProperties: false
@@ -56,6 +63,11 @@ module.exports = {
5663
const useHyphenated = option !== 'never'
5764
/** @type {string[]} */
5865
const ignoredAttributes = (optionsPayload && optionsPayload.ignore) || []
66+
/** @type {RegExp[]} */
67+
const ignoredTagsRegexps = (
68+
(optionsPayload && optionsPayload.ignoreTags) ||
69+
[]
70+
).map(toRegExp)
5971
const autofix = Boolean(optionsPayload && optionsPayload.autofix)
6072

6173
const caseConverter = casing.getConverter(
@@ -99,9 +111,20 @@ module.exports = {
99111
return useHyphenated ? value.toLowerCase() === value : !/-/.test(value)
100112
}
101113

114+
/** @param {string} name */
115+
function isIgnoredTagName(name) {
116+
return ignoredTagsRegexps.some((re) => re.test(name))
117+
}
118+
102119
return utils.defineTemplateBodyVisitor(context, {
103120
"VAttribute[directive=true][key.name.name='on']"(node) {
104-
if (!utils.isCustomComponent(node.parent.parent)) return
121+
const element = node.parent.parent
122+
if (
123+
!utils.isCustomComponent(element) ||
124+
isIgnoredTagName(element.rawName)
125+
) {
126+
return
127+
}
105128
if (!node.key.argument || node.key.argument.type !== 'VIdentifier') {
106129
return
107130
}

‎tests/lib/rules/attribute-hyphenation.js

Copy file name to clipboardExpand all lines: tests/lib/rules/attribute-hyphenation.js
+66Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,26 @@ ruleTester.run('attribute-hyphenation', rule, {
8585
filename: 'test.vue',
8686
code: '<template><div><custom :myName.sync="prop"></custom></div></template>',
8787
options: ['never']
88+
},
89+
{
90+
filename: 'test.vue',
91+
code: `
92+
<template>
93+
<VueComponent my-prop></VueComponent>
94+
<custom-component my-prop></custom-component>
95+
</template>
96+
`,
97+
options: ['never', { ignoreTags: ['VueComponent', '/^custom-/'] }]
98+
},
99+
{
100+
filename: 'test.vue',
101+
code: `
102+
<template>
103+
<VueComponent myProp="prop"></VueComponent>
104+
<custom-component myProp="prop"></custom-component>
105+
</template>
106+
`,
107+
options: ['always', { ignoreTags: ['VueComponent', '/^custom-/'] }]
88108
}
89109
],
90110

@@ -450,6 +470,52 @@ ruleTester.run('attribute-hyphenation', rule, {
450470
line: 1
451471
}
452472
]
473+
},
474+
{
475+
code: `
476+
<template>
477+
<custom my-prop/>
478+
<CustomComponent my-prop/>
479+
</template>
480+
`,
481+
output: `
482+
<template>
483+
<custom myProp/>
484+
<CustomComponent my-prop/>
485+
</template>
486+
`,
487+
options: ['never', { ignoreTags: ['CustomComponent'] }],
488+
errors: [
489+
{
490+
message: "Attribute 'my-prop' can't be hyphenated.",
491+
type: 'VIdentifier',
492+
line: 3,
493+
column: 17
494+
}
495+
]
496+
},
497+
{
498+
code: `
499+
<template>
500+
<custom myProp/>
501+
<CustomComponent myProp/>
502+
</template>
503+
`,
504+
output: `
505+
<template>
506+
<custom my-prop/>
507+
<CustomComponent myProp/>
508+
</template>
509+
`,
510+
options: ['always', { ignoreTags: ['CustomComponent'] }],
511+
errors: [
512+
{
513+
message: "Attribute 'myProp' must be hyphenated.",
514+
type: 'VIdentifier',
515+
line: 3,
516+
column: 17
517+
}
518+
]
453519
}
454520
]
455521
})

‎tests/lib/rules/v-on-event-hyphenation.js

Copy file name to clipboardExpand all lines: tests/lib/rules/v-on-event-hyphenation.js
+70Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,32 @@ tester.run('v-on-event-hyphenation', rule, {
4444
</template>
4545
`,
4646
options: ['never', { ignore: ['custom'] }]
47+
},
48+
{
49+
code: `
50+
<template>
51+
<VueComponent v-on:custom-event="events"/>
52+
</template>
53+
`,
54+
options: ['never', { ignore: ['custom-event'] }]
55+
},
56+
{
57+
code: `
58+
<template>
59+
<VueComponent v-on:custom-event="events"/>
60+
<custom-component v-on:custom-event="events"/>
61+
</template>
62+
`,
63+
options: ['never', { ignoreTags: ['/^Vue/', 'custom-component'] }]
64+
},
65+
{
66+
code: `
67+
<template>
68+
<VueComponent v-on:customEvent="events"/>
69+
<custom-component v-on:customEvent="events"/>
70+
</template>
71+
`,
72+
options: ['always', { ignoreTags: ['/^Vue/', 'custom-component'] }]
4773
}
4874
],
4975
invalid: [
@@ -179,6 +205,50 @@ tester.run('v-on-event-hyphenation', rule, {
179205
"v-on event '@upDate:model-value' can't be hyphenated.",
180206
"v-on event '@up-date:model-value' can't be hyphenated."
181207
]
208+
},
209+
{
210+
code: `
211+
<template>
212+
<VueComponent v-on:custom-event="events"/>
213+
<CustomComponent v-on:custom-event="events"/>
214+
</template>
215+
`,
216+
output: `
217+
<template>
218+
<VueComponent v-on:customEvent="events"/>
219+
<CustomComponent v-on:custom-event="events"/>
220+
</template>
221+
`,
222+
options: ['never', { autofix: true, ignoreTags: ['CustomComponent'] }],
223+
errors: [
224+
{
225+
message: "v-on event 'v-on:custom-event' can't be hyphenated.",
226+
line: 3,
227+
column: 23
228+
}
229+
]
230+
},
231+
{
232+
code: `
233+
<template>
234+
<VueComponent v-on:customEvent="events"/>
235+
<CustomComponent v-on:customEvent="events"/>
236+
</template>
237+
`,
238+
output: `
239+
<template>
240+
<VueComponent v-on:custom-event="events"/>
241+
<CustomComponent v-on:customEvent="events"/>
242+
</template>
243+
`,
244+
options: ['always', { autofix: true, ignoreTags: ['CustomComponent'] }],
245+
errors: [
246+
{
247+
message: "v-on event 'v-on:customEvent' must be hyphenated.",
248+
line: 3,
249+
column: 23
250+
}
251+
]
182252
}
183253
]
184254
})

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.