Where multiple, equally good options exist, an arbitrary choice can be made to ensure consistency. In these rules, we describe each acceptable option and suggest a default choice. That means you can feel free to make a different choice in your own codebase, as long as you're consistent and have a good reason. Please do have a good reason though! By adapting to the community standard, you will:
- Train your brain to more easily parse most of the community code you encounter
- Be able to copy and paste most community code examples without modification
- Often find new hires are already accustomed to your preferred coding style, at least in regards to Vue
Component/instance options should be ordered consistently.
This is the default order we recommend for component options. They're split into categories, so you'll know where to add new properties from plugins.
-
Global Awareness (requires knowledge beyond the component)
name
-
Template Compiler Options (changes the way templates are compiled)
compilerOptions
-
Template Dependencies (assets used in the template)
components
directives
-
Composition (merges properties into the options)
extends
mixins
provide
/inject
-
Interface (the interface to the component)
inheritAttrs
props
emits
-
Composition API (the entry point for using the Composition API)
setup
-
Local State (local reactive properties)
data
computed
-
Events (callbacks triggered by reactive events)
watch
- Lifecycle Events (in the order they are called)
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated
deactivated
beforeUnmount
unmounted
errorCaptured
renderTracked
renderTriggered
-
Non-Reactive Properties (instance properties independent of the reactivity system)
methods
-
Rendering (the declarative description of the component output)
template
/render
The attributes of elements (including components) should be ordered consistently.
This is the default order we recommend for component options. They're split into categories, so you'll know where to add custom attributes and directives.
-
Definition (provides the component options)
is
-
List Rendering (creates multiple variations of the same element)
v-for
-
Conditionals (whether the element is rendered/shown)
v-if
v-else-if
v-else
v-show
v-cloak
-
Render Modifiers (changes the way the element renders)
v-pre
v-once
-
Global Awareness (requires knowledge beyond the component)
id
-
Unique Attributes (attributes that require unique values)
ref
key
-
Two-Way Binding (combining binding and events)
v-model
-
Other Attributes (all unspecified bound & unbound attributes)
-
Events (component event listeners)
v-on
-
Content (overrides the content of the element)
v-html
v-text
You may want to add one empty line between multi-line properties, particularly if the options can no longer fit on your screen without scrolling.
When components begin to feel cramped or difficult to read, adding spaces between multi-line properties can make them easier to skim again. In some editors, such as Vim, formatting options like this can also make them easier to navigate with the keyboard.
props: {
value: {
type: String,
required: true
},
focused: {
type: Boolean,
default: false
},
label: String,
icon: String
},
computed: {
formattedValue() {
// ...
},
inputClasses() {
// ...
}
}
// No spaces are also fine, as long as the component
// is still easy to read and navigate.
props: {
value: {
type: String,
required: true
},
focused: {
type: Boolean,
default: false
},
label: String,
icon: String
},
computed: {
formattedValue() {
// ...
},
inputClasses() {
// ...
}
}
Single-File Components should always order <script>
, <template>
, and <style>
tags consistently, with <style>
last, because at least one of the other two is always necessary.
<style>/* ... */</style>
<script>/* ... */</script>
<template>...</template>
<!-- ComponentA.vue -->
<script>/* ... */</script>
<template>...</template>
<style>/* ... */</style>
<!-- ComponentB.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>
<!-- ComponentA.vue -->
<script>/* ... */</script>
<template>...</template>
<style>/* ... */</style>
<!-- ComponentB.vue -->
<script>/* ... */</script>
<template>...</template>
<style>/* ... */</style>
<!-- ComponentA.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>
<!-- ComponentB.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>