Reactivity Fundamentals
Reactivity Fundamentals#
:::tip API Preference This page and many other chapters later in the guide contain different content for the Options API and the Composition API. Your current preference is Composition API. You can toggle between the API styles using the "API Preference" switches at the top of the left sidebar. :::
## Declaring Reactive State \*\* {#declaring-reactive-state-1}
### `ref()` \*\* {#ref}
In Composition API, the recommended way to declare reactive state is using the [`ref()`](/api/reactivity-core#ref) function:
`ref()` takes the argument and returns it wrapped within a ref object with a `.value` property:
> See also: [Typing Refs](/guide/typescript/composition-api#typing-ref)
To access refs in a component's template, declare and return them from a component's `setup()` function:
```js{5,9-11}
import { ref } from 'vue'
export default {
// `setup` is a special hook dedicated for the Composition API.
setup() {
const count = ref(0)
// expose the ref to the template
return {
count
}
}
}
Notice that we did **not** need to append `.value` when using the ref in the template. For convenience, refs are automatically unwrapped when used inside templates (with a few [caveats](#caveat-when-unwrapping-in-templates)).
You can also mutate a ref directly in event handlers:
```vue-html{1}
Exposed methods can then be used as event handlers:
```vue-html{1}
[Try it in the Playground](https://play.vuejs.org/#eNo9jUEKgzAQRa8yZKMiaNcllvYe2dgwQqiZhDhxE3L3jrW4/DPvv1/UK8Zhz6juSm82uciwIef4MOR8DImhQMIFKiwpeGgEbQwZsoE2BhsyMUwH0d66475ksuwCgSOb0CNx20ExBCc77POase8NVUN6PBdlSwKjj+vMKAlAvzOzWJ52dfYzGXXpjPoBAKX856uopDGeFfnq8XKp+gWq4FAi)
Top-level imports, variables and functions declared in `
import { ref } from 'vue'
const count = ref(0)
const count = ref(0)
console.log(count) // { value: 0 }
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
```vue-html
<div>{{ count }}</div>
For more complex logic, we can declare functions that mutate refs in the same scope and expose them as methods alongside the state:
```js{7-10,15}
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
function increment() {
// .value is needed in JavaScript
count.value++
}
// don't forget to expose the function as well.
return {
count,
increment
}
}
}
Here's the example live on [Codepen](https://codepen.io/vuejs-examples/pen/WNYbaqo), without using any build tools.
### `<script setup>` \*\* {#script-setup}
Manually exposing state and methods via `setup()` can be verbose. Luckily, it can be avoided when using [Single-File Components (SFCs)](/guide/scaling-up/sfc). We can simplify the usage with `<script setup>`:
```vue{1}
<script setup>
import { ref } from 'vue'
const count = ref(0)
function increment() {
count.value++
}
</script>
<template>
<button @click="increment">
{{ count }}
</button>
</template>