zwe1ch/vscode-vuenify
VS Code extension for deterministic Vue SFC template formatting and attribute ordering.
Vuenify
Opinionated Vue SFC formatter for <template> blocks.
Vuenify focuses on deterministic attribute formatting inside Vue Single File Components:
- Sort static
classattributes - Normalize Vue directives (
v-bind,v-on,v-slot) - Order directives by priority
- Order attributes (value first, then boolean)
- Stable, idempotent formatting
- Safe SFC offset handling (script/style untouched)
It formats only the structure of attributes and directives inside <template>.
It does not:
- Format JavaScript
- Format CSS
- Re-indent markup
- Replace your general-purpose formatter
Vuenify can be used in three ways:
- π§ As a Source Action (runs on save after formatting)
- π§© As the default Vue formatter
βΆοΈ Manually via command palette commands
β¨ Features
1οΈβ£ Sort Static Classes
Sort static class attributes alphabetically and optionally remove duplicates.
Before
<div class="b a b c"></div>After
<div class="a b c"></div>Controlled by:
vuenify.classes.sortvuenify.classes.removeDuplicatesvuenify.classes.layout
2οΈβ£ Normalize Vue Directives
Convert between long and shorthand forms:
v-bind:fooβ:foov-on:clickβ@clickv-slot:headerβ#header
Before
<div v-bind:foo="bar" v-on:click="handle"></div>After (short mode)
<div :foo="bar" @click="handle"></div>Supports:
- Modifiers (
.stop,.prevent,.camel) - Dynamic arguments (
v-bind:[foo]) - Same-name bindings (
:src="src")
Controlled by:
vuenify.directives.normalizevuenify.directives.stylevuenify.directives.sameName
3οΈβ£ Directive Ordering
Directives are ordered by configurable priority.
Default priority
["if", "else", "else-if", "for", "on", "model", "bind"]Before
<div v-bind="a" v-if="visible" v-model="value"></div>After
<div v-if="visible" v-model="value" v-bind="a"></div>Controlled by:
vuenify.order.directivesvuenify.order.directivePriority
Unknown directives are sorted alphabetically after prioritized ones.
4οΈβ£ Attribute Ordering
Non-directive attributes can be sorted:
- Attributes with values first
- Boolean attributes after
- Alphabetical within groups
Before
<input disabled type="text" id="field" />After
<input id="field" type="text" disabled />Controlled by:
vuenify.order.attributesvuenify.order.layout
5οΈβ£ Deterministic Tag Rebuild
Opening tags are fully rebuilt to guarantee:
- Deterministic output
- Idempotent formatting
- No partial rewrites
- Stable ordering
Script and style blocks are never modified.
π Usage & Setup
You can configure Vuenify either:
- via the Settings UI (search for βVuenifyβ), or
- in
settings.json(recommended when you want to copy/paste configs)
Option 1 β Source Action Mode
Run Vuenify as a structural pass on save.
"[vue]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.vuenify": "always"
}
}This works independently of whichever formatter you use.
If another formatter is configured, it runs first.
Vuenify runs afterwards as a structural normalization step.
Option 2 β Use as Default Vue Formatter
Let Vuenify handle Vue formatting directly:
"[vue]": {
"editor.defaultFormatter": "zwe1ch.vuenify",
"editor.formatOnSave": true
}Option 3 β Manual Commands
Available in the Command Palette:
- Vuenify: Sort Classes
- Vuenify: Normalize Directives
- Vuenify: Order Attributes & Directives
βοΈ Settings
All settings are defined under the Vuenify namespace.
vuenify.classes.sort
Type: boolean
Default: true
Sort static class attributes alphabetically.
vuenify.classes.removeDuplicates
Type: boolean
Default: true
Remove duplicate class names.
vuenify.classes.layout
Type: "inline" | "preserve"
Default: "inline"
Controls how class attribute whitespace is handled.
inlineβ Always rebuild as single-line class attributepreserveβ Keep original internal whitespace
vuenify.directives.normalize
Type: boolean
Default: true
Normalize supported Vue directives.
vuenify.directives.style
Type: "short" | "long"
Default: "short"
Directive style to use when normalizing.
shortβ:foo,@clicklongβv-bind:foo,v-on:click
vuenify.directives.sameName
Type: "ignore" | "removeValue" | "addValue"
Default: "ignore"
Controls handling of same-name bindings:
<img :src="src" />Options:
ignoreremoveValueβ:srcaddValueβv-bind:src="src"
vuenify.order.directives
Type: boolean
Default: true
Enable directive ordering.
vuenify.order.directivePriority
Type: string[]
Default:
["if", "else", "else-if", "for", "on", "model", "bind"]Custom priority order for Vue directives.
vuenify.order.attributes
Type: boolean
Default: true
Sort non-directive attributes (value first, then boolean).
vuenify.order.layout
Type: "inline" | "preserve"
Default: "inline"
Controls whitespace handling when attributes are reordered.
inlineβ All attributes rebuilt into a single linepreserveβ Preserve existing line breaks
π§ Design Principles
- Deterministic output
- Idempotent formatting
- No partial attribute rewrites
- Safe SFC parsing via
@vue/compiler-sfc - Stable sorting behavior
- Script & style blocks untouched
π License
MIT