Skip to content

Commit 6f892ba

Browse files
ota-meshiHiroki Osamearmano2privatenumber
authored
Add vue/no-duplicate-attr-inheritance rule (from #627) (#1144)
* Added no-duplicate-attr-inheritence rule * New rule no-duplicate-attr-inheritance * New rule no-duplicate-attr-inheritance * Code to work with Node v6.14.4 * Remove category Co-Authored-By: hirokiosame <[email protected]> * Update Co-authored-by: Hiroki Osame <[email protected]> Co-authored-by: Armano <[email protected]> Co-authored-by: hirokiosame <[email protected]>
1 parent f3331bf commit 6f892ba

File tree

5 files changed

+233
-0
lines changed

5 files changed

+233
-0
lines changed

Diff for: docs/rules/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ For example:
282282
| [vue/match-component-file-name](./match-component-file-name.md) | require component name property to match its file name | |
283283
| [vue/max-len](./max-len.md) | enforce a maximum line length | |
284284
| [vue/no-boolean-default](./no-boolean-default.md) | disallow boolean defaults | :wrench: |
285+
| [vue/no-duplicate-attr-inheritance](./no-duplicate-attr-inheritance.md) | enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"` | |
285286
| [vue/no-empty-pattern](./no-empty-pattern.md) | disallow empty destructuring patterns | |
286287
| [vue/no-irregular-whitespace](./no-irregular-whitespace.md) | disallow irregular whitespace | |
287288
| [vue/no-reserved-component-names](./no-reserved-component-names.md) | disallow the use of reserved names in component definitions | |

Diff for: docs/rules/no-duplicate-attr-inheritance.md

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
pageClass: rule-details
3+
sidebarDepth: 0
4+
title: vue/no-duplicate-attr-inheritance
5+
description: enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"`
6+
---
7+
# vue/no-duplicate-attr-inheritance
8+
> enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"`
9+
10+
## :book: Rule Details
11+
12+
This rule aims to prevent duplicated attribute inheritance.
13+
This rule to warn to apply `inheritAttrs: false` when it detects `v-bind="$attrs"` being used.
14+
15+
<eslint-code-block :rules="{'vue/no-duplicate-attr-inheritance': ['error']}">
16+
17+
```vue
18+
<template>
19+
<MyInput v-bind="$attrs" />
20+
</template>
21+
<script>
22+
export default {
23+
/* ✓ GOOD */
24+
inheritAttrs: false
25+
}
26+
```
27+
28+
</eslint-code-block>
29+
30+
<eslint-code-block :rules="{'vue/no-duplicate-attr-inheritance': ['error']}">
31+
32+
```vue
33+
<template>
34+
<MyInput v-bind="$attrs" />
35+
</template>
36+
<script>
37+
export default {
38+
/* ✗ BAD */
39+
// inheritAttrs: true (default)
40+
}
41+
```
42+
43+
</eslint-code-block>
44+
45+
### Options
46+
47+
Nothing.
48+
49+
## Further Reading
50+
51+
- [API - inheritAttrs](https://vuejs.org/v2/api/index.html#inheritAttrs)
52+
53+
## :mag: Implementation
54+
55+
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-duplicate-attr-inheritance.js)
56+
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-duplicate-attr-inheritance.js)

Diff for: lib/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ module.exports = {
5858
'no-deprecated-v-on-number-modifiers': require('./rules/no-deprecated-v-on-number-modifiers'),
5959
'no-deprecated-vue-config-keycodes': require('./rules/no-deprecated-vue-config-keycodes'),
6060
'no-dupe-keys': require('./rules/no-dupe-keys'),
61+
'no-duplicate-attr-inheritance': require('./rules/no-duplicate-attr-inheritance'),
6162
'no-duplicate-attributes': require('./rules/no-duplicate-attributes'),
6263
'no-empty-pattern': require('./rules/no-empty-pattern'),
6364
'no-irregular-whitespace': require('./rules/no-irregular-whitespace'),

Diff for: lib/rules/no-duplicate-attr-inheritance.js

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* @fileoverview Disable inheritAttrs when using v-bind="$attrs"
3+
* @author Hiroki Osame
4+
*/
5+
'use strict'
6+
7+
const utils = require('../utils')
8+
9+
// ------------------------------------------------------------------------------
10+
// Rule Definition
11+
// ------------------------------------------------------------------------------
12+
13+
module.exports = {
14+
meta: {
15+
type: 'suggestion',
16+
docs: {
17+
description: 'enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"`',
18+
categories: undefined,
19+
recommended: false,
20+
url: 'https://eslint.vuejs.org/rules/no-duplicate-attr-inheritance.html'
21+
},
22+
fixable: null,
23+
schema: [
24+
// fill in your schema
25+
]
26+
},
27+
28+
create (context) {
29+
let inheritsAttrs = true
30+
31+
return Object.assign(
32+
utils.executeOnVue(context, (node) => {
33+
const inheritAttrsProp = node.properties.find(prop => (prop.type === 'Property' && utils.getStaticPropertyName(prop) === 'inheritAttrs'))
34+
35+
if (inheritAttrsProp && inheritAttrsProp.value.type === 'Literal') {
36+
inheritsAttrs = inheritAttrsProp.value.value
37+
}
38+
}),
39+
utils.defineTemplateBodyVisitor(context, {
40+
"VAttribute[directive=true][key.name.name='bind'][key.argument=null] > VExpressionContainer" (node) {
41+
if (!inheritsAttrs) {
42+
return
43+
}
44+
const attrsRef = node.references.find(reference => {
45+
if (reference.variable != null) {
46+
// Not vm reference
47+
return false
48+
}
49+
return reference.id.name === '$attrs'
50+
})
51+
52+
if (attrsRef) {
53+
context.report({
54+
node: attrsRef.id,
55+
message: 'Set "inheritAttrs" to false.'
56+
})
57+
}
58+
}
59+
})
60+
)
61+
}
62+
}

Diff for: tests/lib/rules/no-duplicate-attr-inheritance.js

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/**
2+
* @fileoverview Disable inheritAttrs when using v-bind=&#34;$attrs&#34;
3+
* @author Hiroki Osame
4+
*/
5+
'use strict'
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
var rule = require('../../../lib/rules/no-duplicate-attr-inheritance')
12+
13+
var RuleTester = require('eslint').RuleTester
14+
15+
// ------------------------------------------------------------------------------
16+
// Tests
17+
// ------------------------------------------------------------------------------
18+
19+
var ruleTester = new RuleTester({
20+
parser: require.resolve('vue-eslint-parser'),
21+
parserOptions: {
22+
ecmaVersion: 2018,
23+
sourceType: 'module'
24+
}
25+
})
26+
ruleTester.run('no-duplicate-attr-inheritance', rule, {
27+
28+
valid: [
29+
{
30+
filename: 'test.vue',
31+
code: '<template><div><div></div></div></template>'
32+
},
33+
{
34+
filename: 'test.vue',
35+
code: `
36+
<template><div><div></div></div></template>
37+
<script>
38+
export default { inheritAttrs: true }
39+
</script>
40+
`
41+
},
42+
{
43+
filename: 'test.vue',
44+
code: `
45+
<template><div><div></div></div></template>
46+
<script>
47+
const data = {};
48+
export default {
49+
...data,
50+
inheritAttrs: true
51+
}
52+
</script>
53+
`
54+
},
55+
{
56+
filename: 'test.vue',
57+
code: `
58+
<template><div><div></div></div></template>
59+
<script>
60+
const inheritAttrs = false;
61+
export default { inheritAttrs }
62+
</script>
63+
`
64+
},
65+
{
66+
filename: 'test.vue',
67+
code: `
68+
<template><div><div v-bind="$attrs"></div></div></template>
69+
<script>
70+
export default { inheritAttrs: false }
71+
</script>
72+
`
73+
},
74+
{
75+
filename: 'test.vue',
76+
code: `
77+
<template><div><div v-bind="$attrs"></div></div></template>
78+
<script>
79+
export default { inheritAttrs: 0 }
80+
</script>
81+
`
82+
},
83+
{
84+
filename: 'test.vue',
85+
code: `
86+
<template><div><div v-bind:foo="$attrs"></div></div></template>
87+
<script>
88+
export default { }
89+
</script>
90+
`
91+
}
92+
],
93+
94+
invalid: [
95+
{
96+
filename: 'test.vue',
97+
code: '<template><div><div v-bind="$attrs"></div></div></template>',
98+
errors: ['Set "inheritAttrs" to false.']
99+
},
100+
{
101+
filename: 'test.vue',
102+
code: `
103+
<template><div><div v-bind="$attrs"></div></div></template>
104+
<script>
105+
export default {
106+
inheritAttrs: true
107+
}
108+
</script>
109+
`,
110+
errors: ['Set "inheritAttrs" to false.']
111+
}
112+
]
113+
})

0 commit comments

Comments
 (0)