Skip to content

Commit 14450d2

Browse files
westberlinerFloEdelmannwaynzh
authored
Add ignoreProps option to vue/prop-name-casing (#2679)
Co-authored-by: Flo Edelmann <[email protected]> Co-authored-by: Wayne Zhang <[email protected]>
1 parent af3700f commit 14450d2

File tree

3 files changed

+115
-5
lines changed

3 files changed

+115
-5
lines changed

docs/rules/prop-name-casing.md

+32-1
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 don't need to follow the specified casing.
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

+15-1
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,6 +16,8 @@ const allowedCaseOptions = ['camelCase', 'snake_case']
1516
/** @param {RuleContext} context */
1617
function create(context) {
1718
const options = context.options[0]
19+
/** @type {RegExp[]} */
20+
const ignoreProps = (context.options[1]?.ignoreProps || []).map(toRegExp)
1821
const caseType = allowedCaseOptions.includes(options) ? options : 'camelCase'
1922
const checker = casing.getChecker(caseType)
2023

@@ -27,7 +30,7 @@ function create(context) {
2730
if (propName == null) {
2831
continue
2932
}
30-
if (!checker(propName)) {
33+
if (!checker(propName) && !ignoreProps.some((re) => re.test(propName))) {
3134
context.report({
3235
node: item.node,
3336
messageId: 'invalidCase',
@@ -64,6 +67,17 @@ module.exports = {
6467
schema: [
6568
{
6669
enum: allowedCaseOptions
70+
},
71+
{
72+
type: 'object',
73+
properties: {
74+
ignoreProps: {
75+
type: 'array',
76+
items: { type: 'string' },
77+
uniqueItems: true
78+
}
79+
},
80+
additionalProperties: false
6781
}
6882
],
6983
messages: {

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

+68-3
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)