Differences and use cases of ref and reactive in Vue 3

Detailed Explanation of ref and reactive in Vue 3

Differences and use cases of ref and reactive in Vue 3

ref ` reactive` and `  reactive reactive` are two core reactive functions in Vue 3’s Composite API, and they have different use cases.

Core differences

characteristicrefreactive
Data typesAny type (primitive types, objects, arrays)Object types only (Object, Array, Map, Set)
Access methodsneed .valueDirect access to properties
ReassignmentSupport (maintain responsiveness)Not supported (will lose responsiveness)
Template usageAutomatic unpacking (not required  .value)Use directly
DeconstructionNeed to  toRefs remain responsiveNeed to  toRefs remain responsive

Detailed explanation

1. ref – Referencing reactive variables

const articles = ref([])

Why use ref here?

// Need to reassign, ref can maintain responsiveness
articles.value = []                    // Empty array
articles.value = newArticles           // Replace entire array
articles.value = [...articles.value, newArticle] // Create new array

// Automatically unpacking in template, no need for. value
// <div v-for="article in articles">

Typical use cases for ref:

  • Arrays that need to be reassigned
  • Basic data types (string, number, boolean)
  • Objects that may be completely replaced
  • Any value that needs responsive wrapping

2. reactive – reactive objects

const newArticle = reactive({
  title: '',
  excerpt: '',
  content: ''
})

Why use reactive here?

// Directly modify attributes without the need for. value
newArticle.title = 'new title'
newArticle.excerpt = 'new summary'
newArticle.content = 'new content'

// The entire form object as a whole has correlations between its attributes
// No need to reassign the entire object

Typical use cases for reactive:

  • form object
  • Configuration object
  • A set of related data
  • Complex objects that do not require reassignment

Actual code comparison

ref example

// Basic type 
const count = ref(0)
count.value++ // Requires .value

// Array
const list = ref([])
list.value.push('item') // Requires .value
list.value = [] // Can be reassigned

// In template: auto-unpacking
// <div>{{ count }}</div>
// <div v-for="item in list">

reactive example

// Object 
const user = reactive({
name: 'John',
age: 25
})
user.name = 'Jane' // Direct access, no need for .value

// Cannot be reassigned
// user = { name: 'Bob' } // This will lose responsiveness (error)

// In the template: use the attribute directly
// <div>{{ user.name }}</div>

When should you use which one?

Cases where ref is used:

// 1. Basic types 
const isLoading = ref(false)
const page = ref(1)
const searchQuery = ref('')

// 2. Arrays that need to be reassigned
const items = ref([])
const selectedItems = ref([])

// 3. Objects that may be replaced
const config = ref({ theme: 'light' })
config.value = { theme: 'dark' } // Can be replaced

When using reactive:

// 1. Form object 
const form = reactive({
username: '',
password: '',
remember: false
})

// 2. Associated configuration
const settings = reactive({
theme: 'dark',
language: 'en',
notifications: true
})

// 3. Complex state object
const state = reactive({
user: null,
permissions: [],
preferences: {}
})

Special Circumstances Handling

Destructuring a reactive object

const state = reactive({ 
count: 0,
name: 'Vue'
})

// Destructuring will lose reactivity (incorrect)
const { count, name } = state

// Use toRefs to maintain reactivity (correct)
const { count, name } = toRefs(state)
count.value++ // Now we need to increment the value

ref unpacking

const objectRef = ref({ count: 0 })

// Automatically unpack in the template
// <div>{{ objectRef.count }}</div>

// Need. value in JavaScript
objectRef.value.count++

Summarize

  • Use `ref` : a primitive type, the value that needs to be reassigned.
  • Use `reactive` : for objects and form data that do not need to be reassigned.