Skip to content

Commit

Permalink
Add vue/no-duplicate-attr-inheritance rule (from #627) (#1144)
Browse files Browse the repository at this point in the history
* 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 <hiroki.osame@gmail.com>

* Update

Co-authored-by: Hiroki Osame <hiroki@weebly.com>
Co-authored-by: Armano <armano2@users.noreply.github.com>
Co-authored-by: hirokiosame <hiroki.osame@gmail.com>
  • Loading branch information
4 people committed May 20, 2020
1 parent f3331bf commit 6f892ba
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/rules/README.md
Expand Up @@ -282,6 +282,7 @@ For example:
| [vue/match-component-file-name](./match-component-file-name.md) | require component name property to match its file name | |
| [vue/max-len](./max-len.md) | enforce a maximum line length | |
| [vue/no-boolean-default](./no-boolean-default.md) | disallow boolean defaults | :wrench: |
| [vue/no-duplicate-attr-inheritance](./no-duplicate-attr-inheritance.md) | enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"` | |
| [vue/no-empty-pattern](./no-empty-pattern.md) | disallow empty destructuring patterns | |
| [vue/no-irregular-whitespace](./no-irregular-whitespace.md) | disallow irregular whitespace | |
| [vue/no-reserved-component-names](./no-reserved-component-names.md) | disallow the use of reserved names in component definitions | |
Expand Down
56 changes: 56 additions & 0 deletions docs/rules/no-duplicate-attr-inheritance.md
@@ -0,0 +1,56 @@
---
pageClass: rule-details
sidebarDepth: 0
title: vue/no-duplicate-attr-inheritance
description: enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"`
---
# vue/no-duplicate-attr-inheritance
> enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"`
## :book: Rule Details

This rule aims to prevent duplicated attribute inheritance.
This rule to warn to apply `inheritAttrs: false` when it detects `v-bind="$attrs"` being used.

<eslint-code-block :rules="{'vue/no-duplicate-attr-inheritance': ['error']}">

```vue
<template>
<MyInput v-bind="$attrs" />
</template>
<script>
export default {
/* ✓ GOOD */
inheritAttrs: false
}
```

</eslint-code-block>

<eslint-code-block :rules="{'vue/no-duplicate-attr-inheritance': ['error']}">

```vue
<template>
<MyInput v-bind="$attrs" />
</template>
<script>
export default {
/* ✗ BAD */
// inheritAttrs: true (default)
}
```

</eslint-code-block>

### Options

Nothing.

## Further Reading

- [API - inheritAttrs](https://vuejs.org/v2/api/index.html#inheritAttrs)

## :mag: Implementation

- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-duplicate-attr-inheritance.js)
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-duplicate-attr-inheritance.js)
1 change: 1 addition & 0 deletions lib/index.js
Expand Up @@ -58,6 +58,7 @@ module.exports = {
'no-deprecated-v-on-number-modifiers': require('./rules/no-deprecated-v-on-number-modifiers'),
'no-deprecated-vue-config-keycodes': require('./rules/no-deprecated-vue-config-keycodes'),
'no-dupe-keys': require('./rules/no-dupe-keys'),
'no-duplicate-attr-inheritance': require('./rules/no-duplicate-attr-inheritance'),
'no-duplicate-attributes': require('./rules/no-duplicate-attributes'),
'no-empty-pattern': require('./rules/no-empty-pattern'),
'no-irregular-whitespace': require('./rules/no-irregular-whitespace'),
Expand Down
62 changes: 62 additions & 0 deletions lib/rules/no-duplicate-attr-inheritance.js
@@ -0,0 +1,62 @@
/**
* @fileoverview Disable inheritAttrs when using v-bind="$attrs"
* @author Hiroki Osame
*/
'use strict'

const utils = require('../utils')

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------

module.exports = {
meta: {
type: 'suggestion',
docs: {
description: 'enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"`',
categories: undefined,
recommended: false,
url: 'https://eslint.vuejs.org/rules/no-duplicate-attr-inheritance.html'
},
fixable: null,
schema: [
// fill in your schema
]
},

create (context) {
let inheritsAttrs = true

return Object.assign(
utils.executeOnVue(context, (node) => {
const inheritAttrsProp = node.properties.find(prop => (prop.type === 'Property' && utils.getStaticPropertyName(prop) === 'inheritAttrs'))

if (inheritAttrsProp && inheritAttrsProp.value.type === 'Literal') {
inheritsAttrs = inheritAttrsProp.value.value
}
}),
utils.defineTemplateBodyVisitor(context, {
"VAttribute[directive=true][key.name.name='bind'][key.argument=null] > VExpressionContainer" (node) {
if (!inheritsAttrs) {
return
}
const attrsRef = node.references.find(reference => {
if (reference.variable != null) {
// Not vm reference
return false
}
return reference.id.name === '$attrs'
})

if (attrsRef) {
context.report({
node: attrsRef.id,
message: 'Set "inheritAttrs" to false.'
})
}
}
})
)
}
}
113 changes: 113 additions & 0 deletions tests/lib/rules/no-duplicate-attr-inheritance.js
@@ -0,0 +1,113 @@
/**
* @fileoverview Disable inheritAttrs when using v-bind=&#34;$attrs&#34;
* @author Hiroki Osame
*/
'use strict'

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

var rule = require('../../../lib/rules/no-duplicate-attr-inheritance')

var RuleTester = require('eslint').RuleTester

// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------

var ruleTester = new RuleTester({
parser: require.resolve('vue-eslint-parser'),
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module'
}
})
ruleTester.run('no-duplicate-attr-inheritance', rule, {

valid: [
{
filename: 'test.vue',
code: '<template><div><div></div></div></template>'
},
{
filename: 'test.vue',
code: `
<template><div><div></div></div></template>
<script>
export default { inheritAttrs: true }
</script>
`
},
{
filename: 'test.vue',
code: `
<template><div><div></div></div></template>
<script>
const data = {};
export default {
...data,
inheritAttrs: true
}
</script>
`
},
{
filename: 'test.vue',
code: `
<template><div><div></div></div></template>
<script>
const inheritAttrs = false;
export default { inheritAttrs }
</script>
`
},
{
filename: 'test.vue',
code: `
<template><div><div v-bind="$attrs"></div></div></template>
<script>
export default { inheritAttrs: false }
</script>
`
},
{
filename: 'test.vue',
code: `
<template><div><div v-bind="$attrs"></div></div></template>
<script>
export default { inheritAttrs: 0 }
</script>
`
},
{
filename: 'test.vue',
code: `
<template><div><div v-bind:foo="$attrs"></div></div></template>
<script>
export default { }
</script>
`
}
],

invalid: [
{
filename: 'test.vue',
code: '<template><div><div v-bind="$attrs"></div></div></template>',
errors: ['Set "inheritAttrs" to false.']
},
{
filename: 'test.vue',
code: `
<template><div><div v-bind="$attrs"></div></div></template>
<script>
export default {
inheritAttrs: true
}
</script>
`,
errors: ['Set "inheritAttrs" to false.']
}
]
})

0 comments on commit 6f892ba

Please sign in to comment.