Skip to content

Commit 2ef5053

Browse files
author
Patrick Herzberg
committed
feat: add ignoreProps option
1 parent efa6182 commit 2ef5053

File tree

3 files changed

+105
-7
lines changed

3 files changed

+105
-7
lines changed

docs/rules/prop-name-casing.md

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,18 @@ export default {
3939

4040
```json
4141
{
42-
"vue/prop-name-casing": ["error", "camelCase" | "snake_case"]
42+
"vue/prop-name-casing": ["error",
43+
"camelCase" | "snake_case",
44+
{
45+
"ignoreProps": []
46+
}
47+
]
4348
}
4449
```
4550

4651
- `"camelCase"` (default) ... Enforce property names in `props` to camel case.
4752
- `"snake_case"` ... Enforce property names in `props` to snake case.
53+
- `ignoreProps` (`string[]`) ... An array of prop names (or patterns) that should be exempt from the case rule check. Use this option for prop names that are intentionally non-compliant, have special naming requirements for Vue components, or are defined by Vue libraries. You can define these entries as literal strings or as regular expressions (written as strings, e.g., `"/^name/"`).
4854

4955
### `"snake_case"`
5056

@@ -67,6 +73,31 @@ export default {
6773

6874
</eslint-code-block>
6975

76+
### `"ignoreProps": ["foo-bar", "/^_[a-z]+/u"]`
77+
78+
<eslint-code-block :rules="{'vue/prop-name-casing': ['error', 'camelCase', {
79+
ignoreProps: ['foo-bar', '/^_[a-z]+/u'] }]}">
80+
81+
```vue
82+
<script>
83+
export default {
84+
props: {
85+
/* ✓ GOOD */
86+
greetingText: String,
87+
foo-bar: String,
88+
_uid: String,
89+
90+
/* ✗ BAD */
91+
'greeting-text': String,
92+
greeting_text: String,
93+
foo_bar: String
94+
}
95+
}
96+
</script>
97+
```
98+
99+
</eslint-code-block>
100+
70101
## :couple: Related Rules
71102

72103
- [vue/attribute-hyphenation](./attribute-hyphenation.md)

lib/rules/prop-name-casing.js

Lines changed: 5 additions & 3 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 allowedCaseOptions = ['camelCase', 'snake_case']
1011

1112
/**
@@ -15,7 +16,8 @@ const allowedCaseOptions = ['camelCase', 'snake_case']
1516
/** @param {RuleContext} context */
1617
function create(context) {
1718
const options = context.options[0]
18-
const ignores = context.options[1]?.ignores || []
19+
/** @type {RegExp[]} */
20+
const ignoreProps = (context.options[1]?.ignoreProps || []).map(toRegExp)
1921
const caseType = allowedCaseOptions.includes(options) ? options : 'camelCase'
2022
const checker = casing.getChecker(caseType)
2123

@@ -28,7 +30,7 @@ function create(context) {
2830
if (propName == null) {
2931
continue
3032
}
31-
if (!checker(propName) || ignores.includes(propName)) {
33+
if (!checker(propName) && !ignoreProps.some((re) => re.test(propName))) {
3234
context.report({
3335
node: item.node,
3436
messageId: 'invalidCase',
@@ -69,7 +71,7 @@ module.exports = {
6971
{
7072
type: 'object',
7173
properties: {
72-
ignores: {
74+
ignoreProps: {
7375
type: 'array',
7476
items: { type: 'string' },
7577
uniqueItems: true

tests/lib/rules/prop-name-casing.js

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ ruleTester.run('prop-name-casing', rule, {
149149
languageOptions
150150
},
151151
{
152-
// valiable computed property name does not warn
152+
// variable computed property name does not warn
153153
filename: 'test.vue',
154154
code: `
155155
export default {
@@ -161,7 +161,7 @@ ruleTester.run('prop-name-casing', rule, {
161161
languageOptions
162162
},
163163
{
164-
// valiable computed property name does not warn
164+
// variable computed property name does not warn
165165
filename: 'test.vue',
166166
code: `
167167
export default {
@@ -359,6 +359,23 @@ ruleTester.run('prop-name-casing', rule, {
359359
parser: require.resolve('@typescript-eslint/parser')
360360
}
361361
}
362+
},
363+
{
364+
filename: 'test.vue',
365+
code: `
366+
export default {
367+
props: {
368+
'ignored-pattern-test': String,
369+
ignored_prop: Number,
370+
validProp: Boolean
371+
}
372+
}
373+
`,
374+
options: [
375+
'camelCase',
376+
{ ignoreProps: ['ignored_prop', '/^ignored-pattern-/'] }
377+
],
378+
languageOptions
362379
}
363380
],
364381

@@ -686,6 +703,54 @@ ruleTester.run('prop-name-casing', rule, {
686703
}
687704
]
688705
}
689-
])
706+
]),
707+
{
708+
filename: 'test.vue',
709+
code: `
710+
export default {
711+
props: {
712+
notIgnored_prop: String,
713+
'other-pattern': Number,
714+
'pattern-valid': String
715+
}
716+
}
717+
`,
718+
options: ['camelCase', { ignoreProps: ['ignored_prop', '/^pattern-/'] }],
719+
languageOptions,
720+
errors: [
721+
{
722+
message: 'Prop "notIgnored_prop" is not in camelCase.',
723+
type: 'Property',
724+
line: 4
725+
},
726+
{
727+
message: 'Prop "other-pattern" is not in camelCase.',
728+
type: 'Property',
729+
line: 5
730+
}
731+
]
732+
},
733+
{
734+
filename: 'test.vue',
735+
code: `
736+
export default {
737+
props: ['notIgnored_prop', 'pattern_invalid', 'validProp', 'pattern-valid']
738+
}
739+
`,
740+
options: ['camelCase', { ignoreProps: ['ignored_prop', '/^pattern-/'] }],
741+
languageOptions,
742+
errors: [
743+
{
744+
message: 'Prop "notIgnored_prop" is not in camelCase.',
745+
type: 'Literal',
746+
line: 3
747+
},
748+
{
749+
message: 'Prop "pattern_invalid" is not in camelCase.',
750+
type: 'Literal',
751+
line: 3
752+
}
753+
]
754+
}
690755
]
691756
})

0 commit comments

Comments
 (0)