How to understand the difference between ref toRef and toRefs in Vue3

How to understand the difference between ref toRef and toRefs in Vue3

Vue3 has added several new methods for creating responsive data. Of course, their respective functions are also different. Each method has its own application scenario. Today we will talk about what are ref toRef and toRefs? What are the differences in how they are used? What is the best way to use it?

1. Basics

1.ref

(1) Generate responsive data of value type and modify the value through .value

<template>
 <div>{{ ageRef }}</div>
</template>

<script>
import { ref } from 'vue'
export default {
 setup() {
  const ageRef = ref(20)

  setInterval(() => {
   ageRef.value += 1
  }, 1000)
  
  return {
   ageRef
  }
 },
}
</script>

The above code defines an ageRef variable and increases ageRef by 1 every second. The value displayed on the page will also increase by 1.

(2) Can be used in reactive

Change the above code to the following, import the reactive definition variable, import the ref definition variable into reactive, and display the reactive variable in the template. The final effect is the same as above (1)

<template>
 <div>{{ info.age }}</div>
</template>

<script>
import { ref, reactive } from 'vue'
export default {
 setup() {
  const ageRef = ref(20)
  const info = reactive({
   age: ageRef
  })
  setInterval(() => {
   ageRef.value += 1
  }, 1000)
  
  return {
   info
  }
 },
}
</script>

(3) Can be used to obtain Dom

<template>
 <div ref="eleDom">ref-dom-test</div>
</template>

<script>
import { ref, onMounted } from 'vue'
export default {
 setup() {
  const eleDom = ref(null)
  onMounted(() => {
   console.log(eleDom.value.innerHTML) // ref-dom-test
  })
  return {
   eleDom 
  }
 },
}

The console of the above code outputs ref-dom-test, indicating that the Dom element has been obtained.
To obtain the Dom element, the following rules must be met

The defined ref variable name must be consistent with the value in the template ref, such as eleDom in the code.

2. toRef

  • Props for a Responsive Object
  • Create a ref with responsiveness
  • The two maintain a reference relationship

Let's look at the following code

<template>
 <div>{{ state.age }} --- {{ ageRef }}</div>
</template>

<script>
import { toRef, reactive } from 'vue'
export default {
 setup() {
  const state = reactive({
   name: 'JL',
   age: 18
  })
  const ageRef = toRef(state, 'age')
  setTimeout(() => {
   state.age = 20
  }, 1000)
  
  setTimeout(() => {
   ageRef.value = 21
  }, 2000)
  
  return {
   state,
   ageRef
  }
 },
}
</script>

In the above code, toRef is used to turn the age property of state into a responsive variable. Then, after 1 second, the age value of state is changed to 20, at which time ageRef will also become 20. After 2 seconds, the value of ageRef is changed to 21, at which time the age value of state will also become 21, indicating that the two maintain a mutual reference relationship.

toRef is for responsiveness, not ordinary objects. If it is used for non-responsiveness, the output result will not be responsive.

3. toRefs

  • Convert a responsive object to a normal object
  • Each property of an object is a corresponding ref
  • The two maintain a reference relationship

Let's look at the following code

<template>
 <div>{{ name }}---{{ age }}</div>
</template>

<script>
import { reactive, toRefs } from 'vue'
export default {
 setup() {
  const state = reactive({
   name: 'JL',
   age: 18
  })

  const stateRefs = toRefs(state)

  setTimeout(() => {
   state.age = 20
  }, 1000)

  setTimeout(() => {
   stateRefs.age.value = 21
  }, 2000)

  return stateRefs
 },
}
</script>

In the above code, toRefs is used to convert state into a normal object. At this time, stateRefs can be directly returned, and name and age can be directly called in the template. Then, after 1 second, the age value of state is changed to 20, and the age value on the page will also become 20; after 2 seconds, the value of name in stateRefs is changed to 21, and the age value on the page will also become 21, indicating that the two maintain a mutual reference relationship.

After toRefs turns the responsive object into a normal object, each attribute has a responsive ref. At this time, you need to use .value to get its value.

4. Best way to use

  • reactive is object responsive, ref is value type responsive
  • Return toRefs(state) or toRef(state, 'xxx') in setup --- (so that state.xxx is not used in template)
  • Ref variables are named with xxxRef
  • When the composite function returns a responsive object, use toRefs

For example:

<template>
 <div>x:{{x}} y:{{y}}</div>
</template>

<script>
import { reactive, toRefs } from 'vue'
export default {
 setup() {
  function test() {
   const state = reactive({
    x: 1,
    y: 2
   })
   return toRefs(state)
  }
  const {x, y} = test()

  setTimeout(() => {
   x.value = 2
  }, 1000)

  return {
   x,
   y
  }
 }
}
</script>

In the above code, the responsive object state is defined in the test function, and it is converted into a normal object and returned through toRefs. At this time, the structure can be assigned, and the value is responsive.

2. In-depth

1. Why do we need ref?

As we mentioned above, using reactive and toRef can also convert value types into responsive ones, so why do we still need ref?

  • Value types are not responsive (proxy)
  • setup(), computed()... may all return value types. If Vue does not define ref, when users need responsive value types, they will create refs by other means (reactive/toRef, reactive/toRefs), which will make the code more confusing.

2. Why does ref need .value

Why does ref need to add a .value to get the value? Why is it so troublesome?

  • ref is an object (will not lose responsiveness), value stores the value
  • Responsiveness is achieved through get and set of .value properties
  • .value is not needed when used for reactive and templates (vue compilation), but is required in other cases

3. Why do we need toRef and toRefs?

  • Original intention: Deconstruct object data without losing responsiveness
  • Premise: It is for responsive objects, not ordinary objects
  • Result: No creation of responsiveness, only continuation of responsiveness

This is the end of this article about how to understand the difference between ref toRef and toRefs in Vue3. For more relevant Vue3 ref toRef and toRefs content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue basically uses --refs to get instances of components or elements
  • Refs and Ref Details in Vue3
  • How to get elements with ref in vue3

<<:  Implementation example of Docker rocketmq deployment

>>:  Notes on upgrading to mysql-connector-java8.0.27

Recommend

Detailed tutorial for springcloud alibaba nacos linux configuration

First download the compressed package of nacos fr...

How to configure nginx to limit the access frequency of the same IP

1. Add the following code to http{} in nginx.conf...

Implementation of Jenkins+Docker continuous integration

Table of contents 1. Introduction to Jenkins 2. I...

The reason why MySQL uses B+ tree as its underlying data structure

We all know that the underlying data structure of...

HTML meta explained

Introduction The meta tag is an auxiliary tag in ...

Vue+Echart bar chart realizes epidemic data statistics

Table of contents 1. First install echarts in the...

Overview and differences between html inline elements and html block-level elements

Block-level element features : •Always occupies a ...

Install MySQL in Ubuntu 18.04 (Graphical Tutorial)

Tip: The following operations are all performed u...

Example of how to deploy Spring Boot using Docker

Here we mainly use spring-boot out of the box, wh...

Detailed explanation of how components communicate in React

1. What is We can split the communication between...

JavaScript object built-in objects, value types and reference types explained

Table of contents Object Object Definition Iterat...

Web developers are concerned about the coexistence of IE7 and IE8

I installed IE8 today. When I went to the Microso...