Vue Rules: Template Formatting
Every rule on this page includes its purpose, prerequisites, configuration, and complete Bad/Good examples. Highlighted lines show what changes; copying an example gives you the complete source. Each rule also states its current support limits.
| Rule | Examples | Purpose |
|---|---|---|
vue/attribute-hyphenation |
Bad · Good | Enforce attribute naming style on custom components |
vue/attribute-order |
Bad · Good | Enforce a consistent order of attributes |
vue/html-quotes |
Bad · Good | Enforce quotes style of HTML attributes |
vue/html-self-closing |
Bad · Good | Enforce self-closing style |
vue/mustache-interpolation-spacing |
Bad · Good | Enforce consistent spacing inside mustache interpolations |
vue/no-boolean-attr-value |
Bad · Good | Disallow explicit values for boolean HTML attributes |
vue/no-inline-style |
Bad · Good | Discourage use of inline style attributes |
vue/no-multi-spaces |
Bad · Good | Disallow multiple consecutive spaces |
vue/prefer-props-shorthand |
Bad · Good | Recommend shorthand syntax for props (Vue 3.4+) |
vue/prop-name-casing |
Bad · Good | Enforce a casing for declared prop names |
vue/valid-attribute-name |
Bad · Good | Require valid attribute names |
All rules · Rule Options · ESLint migration map · Project checks · Attributes across components
vue/attribute-hyphenation
Enforce attribute naming style on custom components
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: Available for supported findings
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: See typed options and defaults.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/attribute-hyphenation": "warn"
}
},
},
});
vp run lint
Bad
The component attribute uses the camelCase spelling firstName.
<template>
<UserCard firstName="Ada" />
</template>
Good
The first-name spelling follows the configured hyphenated component-attribute convention.
<template>
<UserCard first-name="Ada" />
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/attribute-order
Enforce a consistent order of attributes
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/attribute-order": "warn"
}
},
},
});
vp run lint
Bad
The event handler appears before the structural v-if directive and ordinary id attribute.
<template>
<div @click="onClick" v-if="show" id="main"></div>
</template>
Good
v-if comes first, followed by id and then the event handler, following the rule ordering.
<template>
<div v-if="show" id="main" @click="onClick"></div>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/html-quotes
Enforce quotes style of HTML attributes
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: Available for supported findings
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/html-quotes": "warn"
}
},
},
});
vp run lint
Bad
The attributes use single quotes or no quotes instead of the double-quote convention.
<template>
<div class='foo'></div>
<div class=foo></div>
<div v-if='ready'></div>
</template>
Good
Both ordinary attributes and directive expressions use double quotes.
<template>
<div class="foo"></div>
<div v-if="ready"></div>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/html-self-closing
Enforce self-closing style
Default severity: warning
Presets: nuxt, opinionated
Automatic fix: Available for supported findings
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: See typed options and defaults.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/html-self-closing": "warn"
}
},
},
});
vp run lint
Bad
The empty component uses a closing pair, while void img and br elements omit the configured self-closing spelling.
<template>
<MyComponent></MyComponent>
<img>
<br>
</template>
Good
The component and void elements use self-closing syntax; a div with content retains its closing tag.
<template>
<MyComponent />
<div></div>
<div />
<img />
<br />
<div>content</div>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/mustache-interpolation-spacing
Enforce consistent spacing inside mustache interpolations
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: Available for supported findings
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/mustache-interpolation-spacing": "warn"
}
},
},
});
vp run lint
Bad
The text interpolation is missing a space at one or both delimiter boundaries.
<template>
<div>{{text}}</div>
<div>{{ text}}</div>
<div>{{text }}</div>
</template>
Good
Spaces separate the expression from both opening and closing mustache delimiters.
<template>
<div>{{ text }}</div>
<div>{{ foo.bar }}</div>
<div>{{ foo + bar }}</div>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/no-boolean-attr-value
Disallow explicit values for boolean HTML attributes
Default severity: warning
Presets: nuxt, opinionated
Automatic fix: Available for supported findings
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/no-boolean-attr-value": "warn"
}
},
},
});
vp run lint
Bad
The boolean disabled and checked attributes redundantly contain string values.
<template>
<input disabled="disabled" />
<input checked="checked" />
<button disabled="true">Save</button>
</template>
Good
The presence of each boolean attribute expresses the same enabled state without a value.
<template>
<input disabled />
<input checked />
<button disabled>Save</button>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/no-inline-style
Discourage use of inline style attributes
Default severity: warning
Presets: nuxt, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/no-inline-style": "warn"
}
},
},
});
vp run lint
Bad
The static style attribute embeds the color declaration in the element.
<template>
<div style="color: red">Text</div>
</template>
Good
Classes express the fixed color; the ratio-dependent width remains a dynamic style binding, outside the static-attribute check.
<template>
<div class="text-red">Text</div>
<span :class="{ 'text-red': isRed }">Text</span>
<div :style="{ width: `${ratio}%` }">Text</div>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/no-multi-spaces
Disallow multiple consecutive spaces
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: Available for supported findings
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/no-multi-spaces": "warn"
}
},
},
});
vp run lint
Bad
Two spaces separate attributes or the element name and the first attribute.
<template>
<div class="panel"></div>
<div class="panel" id="main"></div>
</template>
Good
Single spaces separate the same attributes.
<template>
<div class="panel"></div>
<div class="panel" id="main"></div>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/prefer-props-shorthand
Recommend shorthand syntax for props (Vue 3.4+)
Default severity: warning
Presets: nuxt, opinionated
Automatic fix: Available for supported findings
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/prefer-props-shorthand": "warn"
}
},
},
});
vp run lint
Bad
Each binding repeats the corresponding variable name, including the camelCase equivalent of a hyphenated argument.
<template>
<MyComponent :foo="foo" />
<MyComponent :user-name="userName" />
<span :style="style" />
<div :aria-label="ariaLabel" />
</template>
Good
Vue 3.4+ same-name binding shorthand removes the repeated expressions; a different source variable such as bar remains explicit.
<template>
<MyComponent :foo />
<MyComponent :user-name />
<span :style />
<div :aria-label />
<MyComponent :foo="bar" />
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/prop-name-casing
Enforce a casing for declared prop names
Default severity: warning
Presets: happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Checks declared prop names, not the casing of attributes passed to a child.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/prop-name-casing": "warn"
}
},
},
});
vp run lint
Bad
The declared prop name user_name uses underscore-separated spelling.
<script setup lang="ts">
defineProps<{ user_name: string }>();
</script>
<template><p>{{ user_name }}</p></template>
Good
The declaration and its template reference use the camelCase name userName.
<script setup lang="ts">
defineProps<{ userName: string }>();
</script>
<template><p>{{ userName }}</p></template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/valid-attribute-name
Require valid attribute names
Default severity: error
Presets: essential, happy-path, nuxt, ecosystem, opinionated
Automatic fix: None; review the suggested change
Applies to: Vue SFC templates and blocks, with script context where the rule requires it
Options: No rule-specific options. Severity and preset selection are configurable.
Bad diagnostic: parser/template
Malformed attribute spelling is diagnosed by parser/template before this defensive rule sees an attribute. Bad therefore reports parser/template; it does not promise a separate vue/valid-attribute-name finding.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/valid-attribute-name": "error"
}
},
},
});
vp run lint
Bad
The quote inside my"attr makes the attribute name malformed. This example produces the parser's parser/template diagnostic rather than promising a separate rule diagnostic.
<template>
<div my"attr="value"></div>
</template>
Good
my-attr is a well-formed attribute name, so the template parser can read the attribute and its value.
<template>
<div my-attr="value"></div>
</template>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.