Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
e02efe9
feat: add `no-duplicate-class-names` rule
Yizack Sep 8, 2025
f162493
docs: add rule details
Yizack Sep 9, 2025
0fd19ef
docs: add changeset
Yizack Sep 9, 2025
2071c01
feat: report conditional expression
Yizack Sep 9, 2025
99139ad
refactor: no need for a 2nd loop
Yizack Sep 9, 2025
ba9bd9b
feat: support `TemplateLiteral` + improve report
Yizack Sep 10, 2025
535b73a
chore: simplify node param
Yizack Sep 10, 2025
1b04b2a
feat: support `BinaryExpression` + preserve spaces
Yizack Sep 10, 2025
f0c52c0
refactor: rename functions and improve code
Yizack Sep 10, 2025
7b641c0
fix: report cross attribute duplicates
Yizack Sep 18, 2025
a375602
test: add more invalid test cases
Yizack Sep 18, 2025
93e9271
Merge remote-tracking branch 'upstream/master'
Yizack Sep 18, 2025
47b5065
test: rename cross-attribute tests + add literal test
Yizack Sep 18, 2025
c7dcaca
fix: find duplicates within unconditional expression nodes + add comm…
Yizack Sep 18, 2025
b30dbed
Merge remote-tracking branch 'upstream/master'
Yizack Sep 18, 2025
d97f4d9
fix: mixed cross node case
Yizack Sep 18, 2025
a46ec4d
docs: add on more bad and use isActive
Yizack Sep 18, 2025
8e78e75
fix: improve error message
Yizack Oct 15, 2025
a569c82
refactor: refactor variable name
Yizack Oct 15, 2025
142bd0b
docs: pick a more common example for the last "good" example
Yizack Oct 15, 2025
9fec4c9
test: add `line`, `column`, `endLine` and `endColumn`
Yizack Oct 15, 2025
2709da8
Merge remote-tracking branch 'upstream/master'
Yizack Oct 15, 2025
fde5af0
test: adjust error message message
Yizack Oct 15, 2025
7cdcd5d
fix: handle `LogicalExpression`
Yizack Oct 17, 2025
4bb29a1
test: fix duplicate-class-logical-expression-in-conditional
Yizack Oct 17, 2025
d98ca00
test: test actual logical expression duplicate in array
Yizack Oct 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/ten-lines-fail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'eslint-plugin-vue': minor
---

Added new [`vue/no-duplicate-class-names`](https://eslint.vuejs.org/rules/no-duplicate-class-names.html) rule
2 changes: 2 additions & 0 deletions docs/rules/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ For example:
| [vue/no-bare-strings-in-template] | disallow the use of bare strings in `<template>` | | :hammer: |
| [vue/no-boolean-default] | disallow boolean defaults | | :hammer: |
| [vue/no-duplicate-attr-inheritance] | enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"` | | :hammer: |
| [vue/no-duplicate-class-names] | disallow duplication of class names in class attributes | :wrench: | :hammer: |
| [vue/no-empty-component-block] | disallow the `<template>` `<script>` `<style>` block to be empty | :wrench: | :hammer: |
| [vue/no-import-compiler-macros] | disallow importing Vue compiler macros | :wrench: | :warning: |
| [vue/no-multiple-objects-in-class] | disallow passing multiple objects in an array to class | | :hammer: |
Expand Down Expand Up @@ -468,6 +469,7 @@ The following rules extend the rules provided by ESLint itself and apply them to
[vue/no-dupe-v-else-if]: ./no-dupe-v-else-if.md
[vue/no-duplicate-attr-inheritance]: ./no-duplicate-attr-inheritance.md
[vue/no-duplicate-attributes]: ./no-duplicate-attributes.md
[vue/no-duplicate-class-names]: ./no-duplicate-class-names.md
[vue/no-empty-component-block]: ./no-empty-component-block.md
[vue/no-empty-pattern]: ./no-empty-pattern.md
[vue/no-export-in-script-setup]: ./no-export-in-script-setup.md
Expand Down
57 changes: 57 additions & 0 deletions docs/rules/no-duplicate-class-names.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
pageClass: rule-details
sidebarDepth: 0
title: vue/no-duplicate-class-names
description: disallow duplication of class names in class attributes
---

# vue/no-duplicate-class-names

> disallow duplication of class names in class attributes

- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> _**This rule has not been released yet.**_ </badge>
- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fix-problems) can automatically fix some of the problems reported by this rule.

## :book: Rule Details

This rule prevents the same class name from appearing multiple times within the same class attribute or directive.

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

```vue
<template>
<!-- ✓ GOOD -->
<div class="foo bar"></div>
<div :class="'foo bar'"></div>
<div :class="{ 'foo bar': isActive }"></div>
<div :class="['foo', 'bar']"></div>
<div :class="isActive ? 'foo' : 'bar'"></div>
<div class="foo" :class="{ bar: isActive }"></div>

<!-- ✗ BAD -->
<div class="foo foo"></div>
<div class="foo bar foo baz bar"></div>
<div :class="'foo foo'"></div>
<div :class="`foo foo`"></div>
<div :class="{ 'foo foo': isActive }"></div>
<div :class="['foo foo']"></div>
<div :class="['foo foo', { 'bar bar baz': isActive }]"></div>
<div :class="isActive ? 'foo foo' : 'bar'"></div>
<div :class="'foo foo ' + 'bar'"></div>
<div class="foo" :class="'foo'"></div>
<div :class="['foo', 'foo']"></div>
<div :class="'foo ' + 'foo'"></div>
<div :class="['foo', { 'foo': isActive }]"></div>
</template>
```

</eslint-code-block>

## :wrench: Options

Nothing.

## :mag: Implementation

- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-duplicate-class-names.js)
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-duplicate-class-names.js)
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ const plugin = {
'no-dupe-v-else-if': require('./rules/no-dupe-v-else-if'),
'no-duplicate-attr-inheritance': require('./rules/no-duplicate-attr-inheritance'),
'no-duplicate-attributes': require('./rules/no-duplicate-attributes'),
'no-duplicate-class-names': require('./rules/no-duplicate-class-names'),
'no-empty-component-block': require('./rules/no-empty-component-block'),
'no-empty-pattern': require('./rules/no-empty-pattern'),
'no-export-in-script-setup': require('./rules/no-export-in-script-setup'),
Expand Down
Loading