Skip to content

Vue components

We write Vue components using TypeScript and the script setup pattern. Read the documentation here.

Props must be defined with valid types using the defineProps macro, and the same goes for emits with the defineEmits macro. When using these macros make sure to leverage the T argument to pass a type Props = {} type definition as opposed to defining the props as an object.

Example 001
TypeScript
type Props = {
  isLoading: boolean
}

defineProps<Props>()

defineEmits<{
  (e: 'onEdit', payload: string): void
}>()
type Props = {
  isLoading: boolean
}

defineProps<Props>()

defineEmits<{
  (e: 'onEdit', payload: string): void
}>()

Template syntax

We reference Vue components using Pascal case to avoid anyone mistaking them for members of the HTML specification. This applies to 1st and 3rd party components.

Example 002
html
<template>
  <div>
    <HeaderComponent>
      <h1>Hello</h1>
    </HeaderComponent>
  </div>
</template>

<script
  lang="ts"
  setup
>
  import HeaderComponent from 'src/HeaderComponent'
</script>
<template>
  <div>
    <HeaderComponent>
      <h1>Hello</h1>
    </HeaderComponent>
  </div>
</template>

<script
  lang="ts"
  setup
>
  import HeaderComponent from 'src/HeaderComponent'
</script>

Rules:

  • Internal component template references use Pascal case
  • External (third party) component template references use Kebab case

Component props

Component props should be split out to multiple lines

Example 003
html
<template>
  <MyButton
    class="hello"
    label="Click me"
    @click="onClick"
  ></MyButton>
</template>
<template>
  <MyButton
    class="hello"
    label="Click me"
    @click="onClick"
  ></MyButton>
</template>

Adding comments to props

Make sure to add comments to props of which it's not immediately clear what their intention is. It is not a bad idea to document all props, as this makes your component more reusable.

Emits

Emits are a powerful way to pass data from child to parent component. But the convention for handling emits are a bit vague in Vue (there aren't really any). Javascript already has a convention for naming eventhandlers, and it start with on (side note, React also follows this convention). We follow this convention:

Don't

Example 004
html
<Component @edit="edit"></Component>

// and from component emit('edit', value)
<Component @edit="edit"></Component>

// and from component emit('edit', value)

Do

Example 005
html
<Component @onEdit="edit"></Component>

// and from component emit('onEdit', value)
<Component @onEdit="edit"></Component>

// and from component emit('onEdit', value)