Home

Search IconIcon to open search

# Directives

v-bind, or :

1
2
<div v-bind:id="dynamicId"></div>
<div :id="dynamicId"></div>

v-on, or @

1
2
<button v-on:click="increment">{{ count }}</button>
<button @click="increment">{{ count }}</button>

You can also use inline handlers:

1
2
<button @click="count++">Add 1</button>
<p>Count is: {{ count }}</p>

v-model
See Form Input Bindings.

v-if, v-else-if, v-else
Conditional rendering!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<script setup>
import { ref } from 'vue'

const awesome = ref(true)

function toggle() {
  awesome.value = !awesome.value
}
</script>

<template>
  <button @click="toggle">toggle</button>
  <h1 v-if="awesome">Vue is awesome!</h1>
  <h1 v-else>Oh no 😢</h1>
</template>

v-for
Rendering lists!
Always use :key binding (it’s a special attribute for v-for stuff). The key allows Vue to accurately move each <li> to match the position of its corresponding object in the array.

1
2
3
4
5
<ul>
  <li v-for="todo in todos" :key="todo.id">
    {{ todo.text }}
  </li>
</ul>

ref
Use this to manipulate the DOM from Vue! Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<script setup>
import { ref, onMounted } from 'vue'

const p = ref(null)

onMounted(() => {
  p.value.textContent = 'mounted!'
})
</script>

<template>
  <p ref="p">hello</p>
</template>

# Lifecycle hooks

The most common are onMounted(), onUpdated() and onUnmounted(). See the docs.

1
2
3
4
5
6
7
<script setup>
import { onMounted } from 'vue'

onMounted(() => {
  console.log(`the component is now mounted.`)
})
</script>

# Watchers

If you need to perform a side-effect when some value changes, use watchers:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script setup>
import { ref, watch } from 'vue'

const todoId = ref(1)
const todoData = ref(null)

async function fetchData() {
  todoData.value = null
  const res = await fetch(
    `https://jsonplaceholder.typicode.com/todos/${todoId.value}`
  )
  todoData.value = await res.json()
}

fetchData()

watch(todoId, fetchData)
</script>

<template>
  <p>Todo id: {{ todoId }}</p>
  <button @click="todoId++">Fetch next todo</button>
  <p v-if="!todoData">Loading...</p>
  <pre v-else>{{ todoData }}</pre>
</template>

# Props

You can pass properties to child components!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<script setup>
import { ref } from 'vue'
import ChildComp from './ChildComp.vue'

const greeting = ref('Hello from parent')
</script>

<template>
  <ChildComp :msg="greeting" />
</template>

ChildComp.vue:

1
2
3
4
5
6
7
8
9
<script setup>
const props = defineProps({
  msg: String
})
</script>

<template>
  <h2>{{ msg || 'No props passed yet' }}</h2>
</template>

# Emits

Pass stuff from child to parent:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<script setup>
import { ref } from 'vue'
import ChildComp from './ChildComp.vue'

const childMsg = ref('No child msg yet')
</script>

<template>
  <ChildComp @response="(msg) => childMsg = msg" />
  <p>{{ childMsg }}</p>
</template>

ChildComp.vue:

1
2
3
4
5
6
7
8
9
<script setup>
const emit = defineEmits(['response'])

emit('response', 'hello from child')
</script>

<template>
  <h2>Child component</h2>
</template>

# Slots

Can put arbitrary html stuff into components:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<script setup>
import { ref } from 'vue'
import ChildComp from './ChildComp.vue'

const msg = ref('from parent')
</script>

<template>
  <ChildComp>Message: {{ msg }}</ChildComp>
</template>

ChildComp.vue:

1
2
3
<template>
  <slot>Fallback content</slot>
</template>

# Class and style bindings

You can do this:

1
<span :class="{ done: todo.done }">{{ todo.text }}</span>

If todo.done is truthy, then done is added to the class list. See more: Class and Style Bindings | Vue.js.