跳到主要内容

Reactivity Fundamentals

Declaring Reactive State

ref() takes the argument and returns it wrapped within a ref object with a .value property

<script setup>

Manually exposing state and methods via setup() can be verbose. Luckily, it can be avoided when using Single-File Components (SFCs). We can simplify the usage with <script setup>

Top-level imports, variables and functions declared in <script setup> are automatically usable in the template of the same component

Why Refs?

When a component is rendered for the first time, Vue tracks every ref that was used during the render. Later on, when a ref is mutated, it will trigger a re-render for components that are tracking it

Deep Reactivity

A ref will make its value deeply reactive. This means you can expect changes to be detected even when you mutate nested objects or arrays

It is also possible to opt-out of deep reactivity with shallow refs

DOM Update Timing

To wait for the DOM update to complete after a state change, you can use the nextTick() global API

reactive()

Unlike a ref which wraps the inner value in a special object, reactive() makes an object itself reactive

Reactive objects are JavaScript Proxies and behave just like normal objects

reactive() converts the object deeply: nested objects are also wrapped with reactive() when accessed. It is also called by ref() internally when the ref value is an object. Similar to shallow refs, there is also the shallowReactive() API for opting-out of deep reactivity

import { reactive } from 'vue'

const state = reactive({ count: 0 })

Limitations of reactive()

  • Limited value types: it only works for object types
  • Cannot replace entire object
  • Not destructure-friendly

Additional Ref Unwrapping Details

As Reactive Object Property

A ref is automatically unwrapped when accessed or mutated as a property of a reactive object. In other words, it behaves like a normal property

const count = ref(0)
const state = reactive({
count
})

console.log(state.count) // 0

state.count = 1
console.log(count.value) // 1

Caveat in Arrays and Collections

Unlike reactive objects, there is no unwrapping performed when the ref is accessed as an element of a reactive array or a native collection type like Map

Caveat when Unwrapping in Templates

Ref unwrapping in templates only applies if the ref is a top-level property in the template render context