# Setup
This section uses single-file component syntax for code examples
This guide assumes that you have already read the Composition API Introduction and Reactivity Fundamentals. Read that first if you are new to Composition API.
# Arguments
When using the setup
function, it will take two arguments:
props
context
Let's dive deeper into how each argument can be used.
# Props
The first argument in the setup
function is the props
argument. Just as you would expect in a standard component, props
inside of a setup
function are reactive and will be updated when new props are passed in.
// MyBook.vue
export default {
props: {
title: String
},
setup(props) {
console.log(props.title)
}
}
2
3
4
5
6
7
8
9
10
WARNING
However, because props
are reactive, you cannot use ES6 destructuring because it will remove props reactivity.
If you need to destructure your props, you can do this by utilizing the toRefs inside of the setup
function:
// MyBook.vue
import { toRefs } from 'vue'
setup(props) {
const { title } = toRefs(props)
console.log(title.value)
}
2
3
4
5
6
7
8
9
If title
is an optional prop, it could be missing from props
. In that case, toRefs
won't create a ref for title
. Instead you'd need to use toRef
:
// MyBook.vue
import { toRef } from 'vue'
setup(props) {
const title = toRef(props, 'title')
console.log(title.value)
}
2
3
4
5
6
7
8
9
# Context
The second argument passed to the setup
function is the context
. The context
is a normal JavaScript object that exposes three component properties:
// MyBook.vue
export default {
setup(props, context) {
// Attributes (Non-reactive object)
console.log(context.attrs)
// Slots (Non-reactive object)
console.log(context.slots)
// Emit Events (Method)
console.log(context.emit)
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
The context
object is a normal JavaScript object, i.e., it is not reactive, this means you can safely use ES6 destructuring on context
.
// MyBook.vue
export default {
setup(props, { attrs, slots, emit }) {
...
}
}
2
3
4
5
6
attrs
and slots
are stateful objects that are always updated when the component itself is updated. This means you should avoid destructuring them and always reference properties as attrs.x
or slots.x
. Also note that unlike props
, attrs
and slots
are not reactive. If you intend to apply side effects based on attrs
or slots
changes, you should do so inside an onUpdated
lifecycle hook.
# Accessing Component Properties
When setup
is executed, the component instance has not been created yet. As a result, you will only be able to access the following properties:
props
attrs
slots
emit
In other words, you will not have access to the following component options:
data
computed
methods
# Usage with Templates
If setup
returns an object, the properties on the object can be accessed in the component's template, as well as the properties of the props
passed into setup
:
<!-- MyBook.vue -->
<template>
<div>{{ collectionName }}: {{ readersNumber }} {{ book.title }}</div>
</template>
<script>
import { ref, reactive } from 'vue'
export default {
props: {
collectionName: String
},
setup(props) {
const readersNumber = ref(0)
const book = reactive({ title: 'Vue 3 Guide' })
// expose to template
return {
readersNumber,
book
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Note that refs returned from setup
are automatically shallow unwrapped when accessed in the template so you shouldn't use .value
in templates.
# Usage with Render Functions
setup
can also return a render function which can directly make use of the reactive state declared in the same scope:
// MyBook.vue
import { h, ref, reactive } from 'vue'
export default {
setup() {
const readersNumber = ref(0)
const book = reactive({ title: 'Vue 3 Guide' })
// Please note that we need to explicitly expose ref value here
return () => h('div', [readersNumber.value, book.title])
}
}
2
3
4
5
6
7
8
9
10
11
12
# Usage of this
Inside setup()
, this
won't be a reference to the current active instance Since setup()
is called before other component options are resolved, this
inside setup()
will behave quite differently from this
in other options. This might cause confusions when using setup()
along other Options API.