# 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:

  1. props
  2. 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)
  }
}
1
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)
}
1
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)
}
1
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)
  }
}
1
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 }) {
    ...
  }
}
1
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>
1
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])
  }
}
1
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.

Deployed on Netlify.
Last updated: 2021-02-12, 17:42:08 UTC