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)