Skip to content

Commit e70eee6

Browse files
feat: Add vue/no-multiple-objects-in-class rule (#1218)
* feat: Add * feat: Add rule, test, and docs * chore: run update * chore: rename no-multiple-objects-in-class * chore: fix docs url * docs: fix pattern * fix: consider bind * chore: remove unused function
1 parent f77e346 commit e70eee6

File tree

5 files changed

+146
-0
lines changed

5 files changed

+146
-0
lines changed

Diff for: docs/rules/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ For example:
286286
| [vue/no-bare-strings-in-template](./no-bare-strings-in-template.md) | disallow the use of bare strings in `<template>` | |
287287
| [vue/no-boolean-default](./no-boolean-default.md) | disallow boolean defaults | :wrench: |
288288
| [vue/no-duplicate-attr-inheritance](./no-duplicate-attr-inheritance.md) | enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"` | |
289+
| [vue/no-multiple-objects-in-class](./no-multiple-objects-in-class.md) | disallow to pass multiple objects into array to class | |
289290
| [vue/no-potential-component-option-typo](./no-potential-component-option-typo.md) | disallow a potential typo in your component property | |
290291
| [vue/no-reserved-component-names](./no-reserved-component-names.md) | disallow the use of reserved names in component definitions | |
291292
| [vue/no-restricted-component-options](./no-restricted-component-options.md) | disallow specific component option | |

Diff for: docs/rules/no-multiple-objects-in-class.md

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
pageClass: rule-details
3+
sidebarDepth: 0
4+
title: vue/no-multiple-objects-in-class
5+
description: disallow to pass multiple objects into array to class
6+
---
7+
# vue/no-multiple-objects-in-class
8+
> disallow to pass multiple objects into array to class
9+
10+
## :book: Rule Details
11+
12+
This rule disallows to pass multiple objects into array to class.
13+
14+
<eslint-code-block :rules="{'vue/no-multiple-objects-in-class': ['error']}">
15+
16+
```vue
17+
<template>
18+
<div>
19+
<!-- ✓ GOOD -->
20+
<div :class="[{'foo': isFoo, 'bar': isBar}]" />
21+
22+
<!-- ✗ BAD -->
23+
<div :class="[{'foo': isFoo}, {'bar': isBar}]" />
24+
</div>
25+
</template>
26+
```
27+
28+
</eslint-code-block>
29+
30+
## :wrench: Options
31+
32+
Nothing.
33+
34+
## :mag: Implementation
35+
36+
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-multiple-objects-in-class.js)
37+
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-multiple-objects-in-class.js)

Diff for: lib/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ module.exports = {
7474
'no-irregular-whitespace': require('./rules/no-irregular-whitespace'),
7575
'no-lifecycle-after-await': require('./rules/no-lifecycle-after-await'),
7676
'no-multi-spaces': require('./rules/no-multi-spaces'),
77+
'no-multiple-objects-in-class': require('./rules/no-multiple-objects-in-class'),
7778
'no-multiple-slot-args': require('./rules/no-multiple-slot-args'),
7879
'no-multiple-template-root': require('./rules/no-multiple-template-root'),
7980
'no-mutating-props': require('./rules/no-mutating-props'),

Diff for: lib/rules/no-multiple-objects-in-class.js

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* @author tyankatsu <https://github.com/tyankatsu0105>
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
'use strict'
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
const { defineTemplateBodyVisitor } = require('../utils')
12+
13+
// ------------------------------------------------------------------------------
14+
// Rule Definition
15+
// ------------------------------------------------------------------------------
16+
17+
/**
18+
* count ObjectExpression element
19+
* @param {VAttribute} node
20+
* @return {number}
21+
*/
22+
function countObjectExpression(node) {
23+
return node.value.expression.elements.filter(
24+
(element) => element.type === 'ObjectExpression'
25+
).length
26+
}
27+
28+
module.exports = {
29+
meta: {
30+
type: 'suggestion',
31+
docs: {
32+
description: 'disallow to pass multiple objects into array to class',
33+
categories: undefined,
34+
url: 'https://eslint.vuejs.org/rules/no-multiple-objects-in-class.html'
35+
},
36+
fixable: null,
37+
schema: [],
38+
messages: {
39+
unexpected: 'Unexpected multiple objects. Merge objects.'
40+
}
41+
},
42+
/** @param {RuleContext} context */
43+
create(context) {
44+
return defineTemplateBodyVisitor(context, {
45+
/** @param {VAttribute} node */
46+
'VAttribute[directive=true][key.argument.name="class"][key.name.name="bind"][value.expression.type="ArrayExpression"]'(
47+
node
48+
) {
49+
if (countObjectExpression(node) > 1) {
50+
context.report({
51+
node,
52+
loc: node.loc,
53+
messageId: 'unexpected'
54+
})
55+
}
56+
}
57+
})
58+
}
59+
}

Diff for: tests/lib/rules/no-multiple-objects-in-class.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* @author tyankatsu <https://github.com/tyankatsu0105>
3+
*/
4+
'use strict'
5+
6+
// ------------------------------------------------------------------------------
7+
// Requirements
8+
// ------------------------------------------------------------------------------
9+
10+
const rule = require('../../../lib/rules/no-multiple-objects-in-class')
11+
const RuleTester = require('eslint').RuleTester
12+
13+
// ------------------------------------------------------------------------------
14+
// Tests
15+
// ------------------------------------------------------------------------------
16+
17+
const ruleTester = new RuleTester({
18+
parser: require.resolve('vue-eslint-parser'),
19+
parserOptions: { ecmaVersion: 2015, sourceType: 'module' }
20+
})
21+
22+
ruleTester.run('no-multiple-objects-in-class', rule, {
23+
valid: [
24+
`<template><div :class="[{'foo': isFoo}]" /></template>`,
25+
`<template><div :class="[{'foo': isFoo, 'bar': isBar}]" /></template>`,
26+
`<template><div v-foo:class="[{'foo': isFoo}, {'bar': isBar}]" /></template>`
27+
],
28+
invalid: [
29+
{
30+
code: `<template><div v-bind:class="[{'foo': isFoo}, {'bar': isBar}]" /></template>`,
31+
errors: [
32+
{
33+
message: 'Unexpected multiple objects. Merge objects.',
34+
type: 'VAttribute'
35+
}
36+
]
37+
},
38+
{
39+
code: `<template><div :class="[{'foo': isFoo}, {'bar': isBar}]" /></template>`,
40+
errors: [
41+
{
42+
message: 'Unexpected multiple objects. Merge objects.',
43+
type: 'VAttribute'
44+
}
45+
]
46+
}
47+
]
48+
})

0 commit comments

Comments
 (0)