Next.js starter your AI actually understands. Ship internal tools in days not weeks. Pre-order $199 $499 → [Get it now]

How to use setup() in Vue 3

The setup() function is the entry point for the Composition API in Vue 3, replacing the scattered data, computed, methods, and lifecycle options of the Options API with a single, cohesive function. As the creator of CoreUI with Vue development experience since 2014, I’ve migrated dozens of complex components from Options API to setup() and the result is consistently more readable and testable code. Everything you return from setup() becomes available in the template — reactive references, computed properties, and methods alike. Understanding setup() is the foundation for all other Composition API features.

Declare reactive state and return it to the template from setup().

// Counter.vue
<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double: {{ double }}</p>
    <button @click="increment">Increment</button>
    <button @click="reset">Reset</button>
  </div>
</template>

<script>
import { ref, computed, onMounted } from 'vue'

export default {
  setup() {
    // Reactive state
    const count = ref(0)

    // Computed property
    const double = computed(() => count.value * 2)

    // Methods
    function increment() {
      count.value++
    }

    function reset() {
      count.value = 0
    }

    // Lifecycle hook
    onMounted(() => {
      console.log('Component mounted, count:', count.value)
    })

    // Everything returned is available in the template
    return { count, double, increment, reset }
  }
}
</script>

Inside setup(), reactive values created with ref must be accessed with .value. In the template, Vue automatically unwraps refs so you write {{ count }} not {{ count.value }}. Lifecycle hooks like onMounted replace the mounted option.

Receiving Props and Emitting Events

Access props and emit events through setup parameters.

import { computed } from 'vue'

export default {
  props: {
    modelValue: {
      type: Number,
      required: true
    },
    label: String
  },

  emits: ['update:modelValue'],

  setup(props, { emit }) {
    const doubled = computed(() => props.modelValue * 2)

    function update(newValue) {
      emit('update:modelValue', newValue)
    }

    return { doubled, update }
  }
}

The first parameter is props — a reactive object. The second is the context object containing emit, attrs, and slots. Destructuring { emit } from context is a common pattern. Always declare emits in the component options for documentation and runtime validation.

Using setup() with

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
The Best Bootstrap Alternative for Developers in 2025
The Best Bootstrap Alternative for Developers in 2025

How to Remove Underline from Link in CSS
How to Remove Underline from Link in CSS

How to return multiple values from a JavaScript function
How to return multiple values from a JavaScript function

How to convert a string to boolean in JavaScript
How to convert a string to boolean in JavaScript

Answers by CoreUI Core Team