VUE3 learning notes (2) - ref and reactive

ref()

In the composed API, it is recommended to use the ref() function to declare reactive state:

import { ref } from 'vue'

const count = ref(0)

ref() Receives parameters and  .value returns them wrapped in a ref object with attributes:

const count = ref(0)

console.log(count) // { value: 0 }
console.log(count.value) // 0

count.value++
console.log(count.value) // 1

When using ref in template we don't need to append  .value. For convenience, refs are automatically unwrapped when used in templates

<div>{
   
   { count }}</div>

For more complex logic, we can declare functions that change the ref in the same scope and expose them as methods along with the state:

<script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <button @click="increment">
    {
   
   { count }}
  </button>
</template>

Why use ref?

When you use a ref in a template and then change the value of the ref, Vue will automatically detect the change and update the DOM accordingly. This is achieved through a reactive system based on dependency tracking. When a component is first rendered, Vue keeps track of every ref used during the rendering process. Then, when a ref is modified, it triggers a re-render of the component tracking it.

In standard JavaScript, detecting access or modification of ordinary variables doesn't work. However, we can intercept the get and set operations of object properties through getter and setter methods.

This  .value property gives Vue a chance to detect when the ref is accessed or modified. Internally, Vue performs tracking in its getters and triggering in its setters. Conceptually, you can think of a ref as an object like this:

// 伪代码,不是真正的实现
const myRef = {
  _value: 0,
  get value() {
    track()
    return this._value
  },
  set value(newValue) {
    this._value = newValue
    trigger()
  }
}

Another benefit of refs is that, unlike normal variables, you can pass refs to functions while retaining access to the latest value and reactive connections. This is useful when refactoring complex logic into reusable code.

Deep responsiveness

Refs can hold any type of value, including deeply nested objects, arrays, or built-in JavaScript data structures, such as  Map.

The simple understanding is that every single object in the complex object will be packaged as responsive.

DOM update timing

When you modify the responsive state, the DOM is automatically updated. However, it should be noted that DOM updates are not synchronous. Vue will buffer all state modifications in the "next tick" update cycle to ensure that no matter how many state modifications you make, each component will only be updated once.

To wait for the DOM update to complete before executing additional code, you can use the nexttick() global API:

import { nextTick } from 'vue'

async function increment() {
  count.value++
  await nextTick()
  // 现在 DOM 已经更新了
}

reactive()

There is another way to declare reactive state, which is using  reactive() an API. Unlike ref which wraps the internal value in a special object, reactive() making the object itself responsive:

import { reactive } from 'vue'

const state = reactive({ count: 0 })

Use in template:

<button @click="state.count++">
  {
   
   { state.count }}
</button>

Reactive objects are JavaScript proxies that behave just like normal objects. The difference is that Vue can intercept access to and modification of all properties of the reactive object in order to track dependencies and trigger updates.

reactive() Objects are converted deeply: when nested objects are accessed, they are also  reactive() wrapped. ref() It is also called internally when the value of ref is an object . Similar to shallow refs, there is also a shallowreactive  API to opt out of deep reactivity.

It is worth noting that reactive() what is returned is a proxy of the original object , which is not equal to the original object:

const raw = {}
const proxy = reactive(raw)

// 代理对象和原始对象不是全等的
console.log(proxy === raw) // false

Only proxy objects are reactive, changes to the original object will not trigger an update. Therefore, the best practice when using Vue's reactive system is  to only use proxy versions of the objects you declare .

To ensure consistent access to the proxy, calling the same original object  reactive() will always return the same proxy object, while calling an existing proxy object  reactive() will return itself:

// 在同一个对象上调用 reactive() 会返回相同的代理
console.log(reactive(raw) === proxy) // true

// 在一个代理上调用 reactive() 会返回它自己
console.log(reactive(proxy) === proxy) // true

The difference between ref and reactive

different data types

ref : Wraps an ordinary JavaScript value into a responsive reference type. It can be understood that ref is a wrapper for ordinary values. Although ref can wrap complex objects, it uses reactive internally to convert it into an object proxy.

reactive: Convert an ordinary JavaScript object (or array) into a reactive proxy object. It can be understood that reactive is a wrapper for objects (or arrays).

Different access methods

ref: Use the .value attribute to access and modify values.

reactive: Properties or elements of an object or array can be accessed and modified directly without using .value.

Updates are triggered in different ways

ref: Trigger updates through ref() or .value assignment.

reactive: Trigger updates by directly modifying properties or elements of an object or array.

Example

import { ref, reactive } from 'vue';

// ref示例
const count = ref(0);
console.log(count.value); // 访问值
count.value += 1; // 修改值

// reactive示例
const state = reactive({
  name: 'Alice',
  age: 25,
});
console.log(state.name); // 访问属性
state.age += 1; // 修改属性

Summarize

1.ref is mainly for basic types. Complex types will use reactive internally to convert them into proxy objects.

2. Responsiveness can update the page for a certain attribute and object (ie, local data update)

3. Responsive update does not update immediately. It will cache the update content first and wait for the arrival of nexttick. To update immediately, you can directly call the nexttick function.

1. Officially recommended to use  ref() as the main API for declaring reactive status.

Reference article: What is the difference between reactive and ref_The difference between ref and reactive_LuoBoof's blog-CSDN blog

Guess you like

Origin blog.csdn.net/yunxiaobaobei/article/details/132698789