Vue Rules: SFC Blocks
Every rule on this page includes its purpose, prerequisites, configuration, and complete Bad/Good examples. Highlighted lines show the changes; copied code keeps the complete source. Each packet states its current support limits.
| Rule | Examples | Purpose |
|---|---|---|
vue/no-preprocessor-lang |
Bad · Good | Discourage CSS preprocessor usage in favor of modern CSS |
vue/no-script-non-standard-lang |
Bad · Good | Discourage non-standard script lang values |
vue/no-src-attribute |
Bad · Good | Discourage src attribute on SFC blocks |
vue/no-template-lang |
Bad · Good | Discourage lang attribute on template block |
vue/require-scoped-style |
Bad · Good | Require scoped attribute on style tags |
vue/sfc-element-order |
Bad · Good | Enforce consistent order of SFC top-level elements |
vue/single-style-block |
Bad · Good | Recommend having a single style block |
vue/warn-custom-block |
Bad · Good | Warn about custom blocks in SFC files |
All rules · Rule Options · ESLint migration map · Project checks · Attributes across components
vue/no-preprocessor-lang
Discourage CSS preprocessor usage in favor of modern CSS
Default severity: warning
Presets: nuxt, opinionated
Automatic fix: Not implemented for SFC lint
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.
Current support: no-sfc-finding
This catalog entry does not currently emit its rule-specific finding through SFC lint. The Bad/Good pair describes the intended convention, not an executable finding. Enabling the ID does not supply the missing SFC check.
Configured ID (currently no SFC finding)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/no-preprocessor-lang": "warn"
}
},
},
});
vp run lint
Bad
The style block selects SCSS with lang. This describes the intended no-preprocessor convention; the current SFC path does not emit this rule.
<template><p>Notice</p></template>
<style lang="scss">
.notice { color: red; }
</style>
Good
The same CSS declarations omit the preprocessor lang. This is the convention repair, not an executable Bad/Good diagnostic difference today.
<template><p>Notice</p></template>
<style>
.notice { color: red; }
</style>
Good illustrates the intended convention; the current SFC path emits neither side's rule-specific finding.
vue/no-script-non-standard-lang
Discourage non-standard script lang values
Default severity: warning
Presets: nuxt, opinionated
Automatic fix: Not implemented for SFC lint
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.
Current support: no-sfc-finding
This catalog entry does not currently emit its rule-specific finding through SFC lint. The Bad/Good pair describes the intended convention, not an executable finding. Enabling the ID does not supply the missing SFC check.
Configured ID (currently no SFC finding)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/no-script-non-standard-lang": "warn"
}
},
},
});
vp run lint
Bad
The script uses CoffeeScript syntax under lang=coffee. The current SFC path does not emit this catalog rule for that language.
<script lang="coffee">
count = 0
</script>
<template><p>Notice</p></template>
Good
The script uses an ordinary TypeScript declaration with lang=ts, illustrating the intended language convention.
<script lang="ts">
const count = 0;
</script>
<template><p>Notice</p></template>
Good illustrates the intended convention; the current SFC path emits neither side's rule-specific finding.
vue/no-src-attribute
Discourage src attribute on SFC blocks
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-src-attribute": "warn"
}
},
},
});
vp run lint
Bad
The SFC blocks delegate their template, script, and style content to src files.
<template src="./template.html"></template>
<script src="./script.ts"></script>
<style src="./style.css"></style>
Good
Each SFC block contains its own content without an external src attribute.
<template>
<p>Hello</p>
</template>
<script setup lang="ts">
const label = "Hello";
</script>
<style scoped>
p {
color: red;
}
</style>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/no-template-lang
Discourage lang attribute on template block
Default severity: warning
Presets: nuxt, opinionated
Automatic fix: Not implemented for SFC lint
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.
Current support: no-sfc-finding
This catalog entry does not currently emit its rule-specific finding through SFC lint. The Bad/Good pair describes the intended convention, not an executable finding. Enabling the ID does not supply the missing SFC check.
Configured ID (currently no SFC finding)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/no-template-lang": "warn"
}
},
},
});
vp run lint
Bad
The template selects Pug through lang. This is an intended HTML-only convention; the current SFC path does not diagnose this catalog ID.
<template lang="pug">
p Notice
</template>
Good
An ordinary HTML template omits lang and uses the paragraph directly. This illustrates the convention without claiming a current SFC finding.
<template>
<p>Notice</p>
</template>
Good illustrates the intended convention; the current SFC path emits neither side's rule-specific finding.
vue/require-scoped-style
Require scoped attribute on style tags
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/require-scoped-style": "warn"
}
},
},
});
vp run lint
Bad
The .button style is unscoped and can affect matching elements outside this component.
<style>
.button {
color: red;
}
</style>
Good
Adding scoped applies Vue's component scope to the same selector and declarations.
<style scoped>
.button {
color: red;
}
</style>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/sfc-element-order
Enforce consistent order of SFC top-level elements
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: See typed options and defaults.
Configuration (Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
lint: {
vize: {
"preset": "incremental",
"rules": {
"vue/sfc-element-order": "warn"
}
},
},
});
vp run lint
Bad
The style block precedes the script block, contrary to the configured SFC block order.
<style scoped>
.panel {
color: red;
}
</style>
<script setup lang="ts">
const label = "Save";
</script>
Good
The blocks follow script → template → style. Projects can choose a different order through this rule's typed option.
<script setup lang="ts">
const label = "Save";
</script>
<template>
<p>{{ label }}</p>
</template>
<style scoped>
p {
color: red;
}
</style>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/single-style-block
Recommend having a single style block
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/single-style-block": "warn"
}
},
},
});
vp run lint
Bad
The component splits its scoped panel and title styles across two style blocks.
<style scoped>
.panel {
color: red;
}
</style>
<style scoped>
.title {
color: blue;
}
</style>
Good
Both selectors stay scoped in one style block, satisfying the single-block convention without dropping either style.
<style scoped>
.panel {
color: red;
}
.title {
color: blue;
}
</style>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.
vue/warn-custom-block
Warn about custom blocks in SFC files
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/warn-custom-block": "warn"
}
},
},
});
vp run lint
Bad
The SFC contains an <i18n> custom block, which needs an external integration beyond ordinary template/script/style processing.
<i18n>
{ "en": { "hello": "Hello" } }
</i18n>
<template>
<p>{{ hello }}</p>
</template>
Good
The example uses standard template and script-setup blocks. This optional portability warning does not mean every custom block is invalid Vue.
<template>
<p>{{ hello }}</p>
</template>
<script setup lang="ts">
const hello = "Hello";
</script>
Good avoids this rule's finding under the configuration above; other rules may still report diagnostics.