VueJS Guidelines
Style Guide
The Vue team has written an excellent style guide which we use as our standard. Please become familiar with the practices and implement them in Zaengle/Vue projects. Items of particular note and any deviations from the official guide will be listed here.
Vue Components
Naming
Reference the naming section of the styleguide for a detailed explanation of the required naming conventions.
Bad - Inconsistent naming convention
components/
|- MyButton.vue
|- VueTable.vue
|- Icon.vue
Good - Tightly coupled, multi-word names
components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue
components/
|- AppButton.vue
|- AppTable.vue
|- AppIcon.vue
components/
|- VButton.vue
|- VTable.vue
|- VIcon.vue
Structure
To make things easier for your teammates, your Vue component should be structured in this order:
- name - *required
- components
- mixins
- model
- props
- data
- computed
- watch
- events
- beforeCreate
- created
- mounted
- beforeUpdated
- updated
- activated
- deactivated
- beforeDestroy
- destroyed
- methods
- render
Templates
If a Vue component has so many props (or listeners, directives, etc.) that they don't fit on one line anymore, you need to put every prop on its own line. Every line needs to be indented with 2 spaces. The closing >
goes on a new unindented line followed by the closing tag.
<template>
<!-- Good -->
<MyComponent my-prop="value" />
</template>
<template>
<!-- Good -->
<MyComponent
v-if="shouldDisplay"
my-prop="value"
@change="handleEvent"
/>
</template>
<template>
<!-- Bad: wrong indentation, closing `>` is not correctly placed -->
<my-component
v-if="shouldDisplay"
myProp="value"
@change="handleEvent">
</my-component>
</template>
Self-Closing Elements
Whenever possible, use self-closing tags for brevity.
<template>
<!-- Good -->
<MyComponent />
</template>
<template>
<!-- Bad -->
<MyComponent></MyComponent>
</template>
v-text
In the cases of simple strings or string concatenation, it is preferred to use v-text
. This keeps tag styles similar.
<template>
<!-- Good -->
<strong v-text="'Packers'" />
<label v-text="`Item ${index}`" />
</template>
<template>
<!-- Bad -->
<strong>Bears</strong>
<label>Item {{ index }}</label>
</template>
Tag Property Order
Tags should follow this order:
v-if/else
orv-show
- id
v-model
- class
- props or dynamic attributes
- event handlers
v-text
<MyComponent
v-if="shouldShow"
id="myId"
v-model="myModel"
class="my-class"
:class="{ 'important': checkIfImportant }"
@event="handleIt"
v-text="'My Label'"
/>
Prop Types
Props should always be given a type
and a required
property. If the prop is not required, then a default
must be provided.
// Good
props: {
headingText: {
type: String,
required: true,
},
subscription: {
type: Object,
required: false,
default: () => ({}),
},
},
// Bad
props: {
headingText: {
type: String,
},
subscription: {
type: Object,
required: false,
},
},
// Bad
props: ['headingText', 'subscription'],