Priority C Rules: Recommended
Note
This Vue.js Style Guide is outdated and needs to be reviewed. If you have any questions or suggestions, please open an issue.
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 order
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
Element attribute order
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
Empty lines in component/instance options
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.
Bad
js
defineProps({
value: {
type: String,
required: true
},
focused: {
type: Boolean,
default: false
},
label: String,
icon: String
})
const formattedValue = computed(() => {
// ...
})
const inputClasses = computed(() => {
// ...
})
Good
js
defineProps({
value: {
type: String,
required: true
},
focused: {
type: Boolean,
default: false
},
label: String,
icon: String
})
const formattedValue = computed(() => {
// ...
})
const inputClasses = computed(() => {
// ...
})
Single-file component top-level element order
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.
Bad
template
<style>/* ... */</style>
<script>/* ... */</script>
<template>...</template>
template
<!-- ComponentA.vue -->
<script>/* ... */</script>
<template>...</template>
<style>/* ... */</style>
<!-- ComponentB.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>
Good
template
<!-- ComponentA.vue -->
<script>/* ... */</script>
<template>...</template>
<style>/* ... */</style>
<!-- ComponentB.vue -->
<script>/* ... */</script>
<template>...</template>
<style>/* ... */</style>
template
<!-- ComponentA.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>
<!-- ComponentB.vue -->
<template>...</template>
<script>/* ... */</script>
<style>/* ... */</style>