SoFunction
Updated on 2025-04-05

vue3 declares responsive state usage (including ref, reactive, toRef, toRefs, etc.)

The data in Vue 3 is based onJavaScript Proxy (Proxy)Implement responsiveness

(The data in vue2 passes()Rewrite methods and array mutation methods to implement responsiveness)

Optional API

Use the data option to declare the responsive state, with the value of the function that returns an object.

  • This function will be called when creating a component instance
  • The object returned by the function will be wrapped with a responsive system.
  data() {
    return {
      count: 1
    }
  },

Things to note

  • The top-level properties of data are avoided$and_Beginning (Vue's built-in API exposed on component instances uses $ as prefix, and also reserves the _ prefix for internal properties.)
  • New properties of component instances not defined in data cannot trigger responsive updates.
  • Always access responsive state via this
  data() {
    return {
      someObject: {}
    }
  },
  mounted() {
    const newObject = {}
     = newObject

    (newObject === ) // false
  }

Here the original newObject does not become responsive.

Combination API

Method one ref 【Recommended】

Ref is recommended for all types of data.

import { ref } from 'vue'

// Define a responsive variable countRef with the initial value of the number 0const countRef = ref(0)

// Get a ref object with .value attribute(countRef ) // { value: 0 }

// Access the value of the ref responsive variable through .value() // 0

// Modify the value of the ref responsive variable through .value++
  • The parameter is the initial value of the responsive variable (when the parameter is an object,ref()Will be called internallyreactive()
  • Returns a ref object with a .value attribute
  • The recommended variable name isRefas a suffix to identify it as a ref object
  • When used in a template, the ref object will be automatically unpacked without using .value
<button @click="countRef++">
  {{ countRef }}
</button>
  • The ref object is automatically unpacked when it is accessed or modified as a property of a responsive object.
const countRef = ref(0)

// See below for details on the usage of reactiveconst state = reactive({
  count:countRef 
})

() // 0, no need to write
 = 1 // No need to write(countRef .value) // 1
  • Another function of ref is to get template references (i.e. this.$refs in vue2)
&lt;script setup&gt;
import { ref, onMounted } from 'vue'

// Get a reference to the template element with the ref attribute input (the ref variable name must be the same as the ref attribute value in the template)const input = ref(null)

// Life cycle: DOM mount is completedonMounted(() =&gt; {
  // The input input box gets focus (note that .value is required here)  ()
})
&lt;/script&gt;

&lt;template&gt;
  &lt;!-- ref The attribute is input Template elements --&gt;
  &lt;input ref="input" /&gt;
&lt;/template&gt;
  • Why ref is needed

Because the responsiveness of vue3 is implemented through proxy, but proxy can only add responsiveness to objects and cannot add responsiveness to value-type data, you need to use the ref() function to first wrap the data of value-type into a ref object with a value attribute to realize the responsiveness of value-type data.

  • Why .value is needed

Because the ref() function returns a ref object, the value of the responsive variable is stored in the value property of the ref object, .value is required when reading and modifying the value of the responsive variable in js. However, in the following cases, for the sake of convenience, vue automatically unpacks the ref object, so there is no need for .value

  • Use ref objects in templates
  • The ref object is accessed or modified as a property of a responsive object

TS declare type to ref

  • ref deduces its type based on the initialization value
// Derived type: Ref<number>const year = ref(2020)
  • However, for relatively complex data types, Ref is required
import { ref } from 'vue'
import type { Ref } from 'vue'

interface userInfo {
  id: number
  name: String
}

const userList: Ref<userInfo[]> = ref([])

Way 2 reactive

Responsiveness used to create object type data.

import { reactive } from 'vue'
const state = reactive({ count: 0 })
<button @click="++">
  {{  }}
</button>
  • reactive() does not need to add ref-like wrappers to the source data, making the object itself responsive
  • reactive() returns a Proxy of the original object, which is not equal to the original object
const raw = {}
const proxy = reactive(raw)

// The proxy object and the original object are not inclusive(proxy === raw) // false

Limitations of reactive()

  • Only used for object type data (objects, arrays, and collection types such as Map, Set), and not for value type data such as string, number, or boolean
  • Replacing the entire object will lose responsiveness (Vue's responsive tracking is implemented through property access), so you can only modify the responsive variables created by reactive() by modifying the properties.
  • Deconstruction will lose responsiveness
const state = reactive({ count: 0 })

// When deconstructed, count has been disconnected fromlet { count } = state
// It will not affect the original statecount++

Other related APIs

vue provides a dedicated API to deconstruct reactive objects (reactive creation) without losing responsives. They do not create reactives (such as ref , reactive), but continue reactives (toRef , toRefs)!

  • toRef()

Create ref based on properties on responsive objects (stay synchronized with source properties)

  • The first parameter is a reactive object (created by reactive)
  • The second parameter is attribute name
const state = reactive({
  foo: 1
})

// Create ref based on the property foo on the responsive object stateconst fooRef = toRef(state, 'foo')

// Changing the ref will update the source attribute++
() // 2

// Changing the source attribute will also update the ref++
() // 3

vue3.3+ has added the function of normalizing values, refs or getters to refs. For details, please refer to the official website.

/api/#toref

  • toRefs()

Convert responsive objects to normal objects whose properties each point to the ref of the corresponding properties of the source object

  • Recommended usage: When a synthetic function returns a responsive object, use toRefs so that the responsive formula is not lost when deconstructing the assignment. (See the example below for details)
const state = reactive({
  foo: 1,
  bar: 2
})

// Get a normal object with each property refconst stateAsRefs = toRefs(state)
/*
 Type of stateAsRefs: {
   foo: Ref<number>,
   bar: Ref<number>
 }
 */

// Change the source attribute, the ref attribute in the Refs object will be changed synchronously++
() // 2

// The ref attribute in the Refs object will change, and the source attribute will be changed synchronously++
() // 3

Application example: Deconstruct object properties and simplify template references

&lt;!-- CombinationAPI --&gt;
&lt;script setup&gt;
import { reactive, toRefs } from "vue";

function getMyInfo() {
  const me = reactive({
    name: "Chaoyang",
    age: 35,
  });

  // Use toRefs to avoid loss of responsiveness  return toRefs(me);
}

// Deconstruct the assignment to facilitate use in templateslet { name, age } = getMyInfo();

const changeName = () =&gt; {
   = "Zhang San";
};
&lt;/script&gt;

&lt;template&gt;
  &lt;p&gt;Name:{{ name }}&lt;/p&gt;
  &lt;p&gt;age:{{ age }}&lt;/p&gt;
  &lt;button @click="changeName"&gt;Change name&lt;/button&gt;
&lt;/template&gt;
  • isRef()

Determine whether it is ref

let age = ref(35)
if (isRef(age)) {
}
  • isReactive()

Determines whether an object is a proxy created by reactive() or shallowReactive().

  • isProxy()

Determines whether an object is a proxy created by reactive(), readonly(), shallowReactive(), or shallowReadonly().

  • unref()

Unpacking the ref object, yesisRef(val) ? : valSyntax sugar

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.