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 or v-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'],