SoFunction
Updated on 2025-04-04

Analysis of the principle of ref and reactive responsiveness in Vue3

Vue3 series 4--ref and reactive responsive

This section mainly introduces the conversion of responsive variables and objects, as well as the conversion of variables and objects between responsive and non-responsive.

1 ref

Accepts an internal value and returns a responsive and mutable ref object. There is only one ref object.valueproperty, pointing to this internal value.

Case

<template>
  <div>
    <button @click="changeMsg">change</button>
    <div>{{ message }}</div>
  </div>
</template>
  
<script setup lang="ts">
let message: string = "I'm message"
  
const changeMsg = () => {
   message = "change msg"
}
</script>
  
<style>
</style>

We cannot change the value of message in this way. It should be that message is not responsive and cannot be tracked by vue. It should be changed to ref. Responsiveness is to display the modified value on the page in real time.

Ref TS corresponding interface:

interface Ref<T> {
  value: T
} // For interface issues,yesTSgrammar,If not clear,Watch it directlyTS

However, after being wrapped by ref, you need to use value to assign values.

<template>
  <div>
    <button @click="changeMsg">change</button>
    <div>{{ message }}</div>
  </div>
</template>
<script setup lang="ts">
import {ref,Ref} from 'vue'
let message:Ref<string> = ref("I'm message")let message= ref<string>("I'm message") // The second method const changeMsg = () => {    = "change msg"
}
</script>
<style>
</style>

2 isref determines whether it is a ref object

import { ref, Ref,isRef } from 'vue'
let message: Ref<string | number> = ref("I'm message")
let notRef:number = 123
const changeMsg = () => {
   = "change msg"
  (isRef(message)); //true
  (isRef(notRef)); //false
}

3 shallowref creates a ref that tracks its own .value changes, but does not make its value responsive

Example 1

Modifying its properties is non-responsive will not change

<template>
  <div>
    <button @click="changeMsg">change</button>
    <div>{{ message }}</div>
  </div>
</template>
  
<script setup lang="ts">
import { Ref, shallowRef } from 'vue'
type Obj = {
  name: string
}
let message: Ref<Obj> = shallowRef({
  name: "Tang Young Master"
})
  
const changeMsg = () => {
   = 'Tang Shao 2'
}
</script>
  
<style>
</style>

Example 2

This is a modified value that can be heard, and the entire object must be modified.

import { Ref, shallowRef } from 'vue'
type Obj = {
  name: string
}
let message: Ref<Obj> = shallowRef({
  name: "Tang Young Master"
})
  
const changeMsg = () => {
   = { name: "Tang Young Master 2" }
}

4 triggerRef

In order to solve the problem of shallowRef, we force update the page DOM, so that the value can be changed.

<template>
  <div>
    <button @click="changeMsg">change</button>
    <div>{{ message }}</div>
  </div>
</template>
  
<script setup lang="ts">
import { Ref, shallowRef,triggerRef } from 'vue'
type Obj = {
  name: string
}
let message: Ref<Obj> = shallowRef({
  name: "Tang Young Master"
})
  
const changeMsg = () => {
   = 'Tang 2'
 triggerRef(message)
}
</script>
  
<style>
</style>

5 customRef

CustomRef , customRef is a factory function that requires us to return an object and implement get and set

<script setup lang="ts">
import { Ref, shallowRef, triggerRef, customRef } from 'vue'
  
function Myref<T>(value: T) {
  return customRef((track, trigger) => {
    return {
      get() {
        track()
        return value
      },
      set(newVal: T) {
        ('set');
        value = newVal
        trigger()
      }
    }
  })
}
  
let message = Myref('Tang Young Master')
const changeMsg = () => {
   = 'Tang Shao 2'
  // triggerRef(message)
}
</script>

6 Reactive uses to bind complex data types

For example, object array

reactiveSource codeConstrain our type, the type must be an object, and it cannot be bound to an ordinary type, and an error will be reported. If you use ref to bind complex data types such as objects or arrays, we can see that the source code actually calls reactive, but it does not require using reactive to modify the value. Value

Basic usage of reactive

import { reactive } from 'vue'
let person = reactive({
   name:"Tang Young Master"
})
 = "Tang Young Master 2"

Asynchronous array assignment problem

// This will not change because it will be out of responsive<br data-filtered="filtered">let person = reactive<number[]>([])setTimeout(() =&gt; {
  person = [1, 2, 3]
  (person);
   
},1000)

Solution 1: push

import { reactive } from 'vue'
let person = reactive<number[]>([])
setTimeout(() => {
  const arr = [1, 2, 3]
  (...arr)
  (person);
   
},1000)

Solution 2: Wrap a layer of objects

type Person = {
  list?:Array<number>
}
let person = reactive<Person>({
   list:[]
})
setTimeout(() => {
  const arr = [1, 2, 3]
   = arr;
  (person);
   
},1000)

7 readonly

Copy a copy of the proxy object and set it to read-only

import { reactive ,readonly} from 'vue'
const person = reactive({count:1})
const copy = readonly(person)
 //++
 ++

8 shallowReactive

Only for shallow data. If it is deep data, it will only change the value and will not change the view.

<template>
  <div>
    <div>{{ state }}</div>
    <button @click="change1">test1</button>
    <button @click="change2">test2</button>
  </div>
</template>
  
<script setup lang="ts">
import { shallowReactive } from 'vue'
  
const obj = {
  a: 1,
  first: {
    b: 2,
    second: {
      c: 3
    }
  }
}
const state = shallowReactive(obj)
function change1() {
   = 7
}
function change2() {
   = 8
   = 9
  (state);
}
  
</script>
<style>
</style> 

9toRef

If the original object is non-responsive, the view will not be updated. The data will change. If the original object is responsive, the view will be updated and the data will be changed.

&lt;template&gt;
   &lt;div&gt;
      &lt;button @click="change"&gt;Button&lt;/button&gt;
      {{state}}
   &lt;/div&gt;
&lt;/template&gt;
  
&lt;script setup lang="ts"&gt;
import { reactive, toRef } from 'vue'
  
const obj = {
   foo: 1,
   bar: 1
}
  
const state = toRef(obj, 'bar')
// bar is converted into a responsive object  
const change = () =&gt; {
   ++
   (obj, state);
}
&lt;/script&gt;

10toRefs

It can help us create ref objects in batches mainly to facilitate our deconstruction and use

import { reactive, toRefs } from 'vue'
const obj = reactive({
   foo: 1,
   bar: 1
})
  
let { foo, bar } = toRefs(obj)
  
++
(foo, bar);

11toRaw

Convert responsive objects into normal objects

import { reactive, toRaw } from 'vue'
const obj = reactive({
   foo: 1,
   bar: 1
})
const state = toRaw(obj)
// Convert responsive objects into ordinary objects  
const change = () =&gt; {
   (obj, state);
}

This is the end of this article about ref and reactive responsive in Vue3. For more related Vue3 ref and reactive responsive content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!