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 14450d2

Browse filesBrowse files
westberlinerFloEdelmannwaynzh
authored
Add ignoreProps option to vue/prop-name-casing (#2679)
Co-authored-by: Flo Edelmann <git@flo-edelmann.de> Co-authored-by: Wayne Zhang <waynzh19@gmail.com>
1 parent af3700f commit 14450d2
Copy full SHA for 14450d2

File tree

3 files changed

+115
-5
lines changed
Filter options

3 files changed

+115
-5
lines changed

‎docs/rules/prop-name-casing.md

Copy file name to clipboardExpand all lines: docs/rules/prop-name-casing.md
+32-1Lines 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 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

Copy file name to clipboardExpand all lines: lib/rules/prop-name-casing.js
+15-1Lines changed: 15 additions & 1 deletion
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

Copy file name to clipboardExpand all lines: tests/lib/rules/prop-name-casing.js
+68-3Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.