9
头图

Vue3 provides developers with ref and reactive two APIs to implement responsive data, which are also the two APIs we often use in Vue3 development projects.

This article introduces these two APIs from an introductory perspective. If there are any mistakes, please discuss and learn together~

The demo code in this article is based on the Vue3 setup syntax.

In the introductory stage, what we need to master is "what is it", "how to use it", and "what should I pay attention to", which is basically the same.

1. How to use reactive API?

reactive method is used to create a responsive object, it receives an object/array parameter and returns a responsive copy of the object. When the property value of the object changes, it will automatically update the place where the object is used.

The following is demonstrated with objects and arrays as parameters:

 import { reactive } from 'vue'

let reactiveObj = reactive({ name : 'Chris1993' });
let setReactiveObj = () => {
  reactiveObj.name = 'Hello Chris1993';
}

let reactiveArr = reactive(['a', 'b', 'c', 'd']);
let setReactiveArr = () => {
  reactiveArr[1] = 'Hello Chris1993';
}

The template content is as follows:

 <template>
  <h2>Vue3 reactive API Base</h2>
  <div>
    Object:{{reactiveObj.name}} 
    <span @click="setReactiveObj">Update</span>
  </div>
  <div>
    Array:{{reactiveArr}} 
    <span @click="setReactiveArr">Update</span>
  </div>
</template>

At this point the page looks like this:

reactive

When we click the Update button respectively, we can see that after the data changes, the content on the view is also updated together:

reactive

2. How to use the ref API?

ref is to convert a primitive data type into a data type with responsive features . There are 7 primitive data types: String / Number / BigInt / Boolean / Symbol / Null / Undefined

When the value of ref is read and modified in JS/TS, you need to use .value to get it, read it in the template, you don't need to use .value .

The following is demonstrated with strings and objects as parameters:

 import { ref } from 'vue'

let refValue = ref('Chris1993');
let setRefValue = () => {
  refValue.value = 'Hello Chris1993';
}
let refObj = ref({ name : 'Chris1993' });
let setRefObj = () => {
  refObj.value.name = 'Hello Chris1993';
}

The template content is as follows:

 <template>
  <h2>Vue3 ref API Base</h2>
  <div>
    String:{{refValue}} 
    <span @click="setRefValue">Update</span>
  </div>
  <div>
    Object:{{refObj.name}}
    <span @click="setRefObj">Update</span>
  </div>
</template>

At this point the page looks like this:

ref

When we click the Update button respectively, we can see that after the data changes, the view content is also updated together:

ref

3. Can reactive be used on deep objects or arrays?

The answer is yes , reactive is implemented based on the ES2015 Proxy API , and its reactivity is all nesting levels of the entire object.

The following is demonstrated with objects and arrays as parameters:

 import { reactive } from 'vue'

let reactiveDeepObj = reactive({
  user: {name : 'Chris1993'}
});
let setReactiveDeepObj = () => {
  reactiveDeepObj.user.name = 'Hello Chris1993';
}

let reactiveDeepArr = reactive(['a', ['a1', 'a2', 'a3'], 'c', 'd']);
let setReactiveDeepArr = () => {
  reactiveDeepArr[1][1] = 'Hello Chris1993';
}

The template content is as follows:

 <template>
  <h2>Vue3 reactive deep API Base</h2>
  <div>
    Object:{{reactiveDeepObj.user.name}}
    <span @click="setReactiveDeepObj">Update</span>
  </div>
  <div>
    Array:{{reactiveDeepArr}}
    <span @click="setReactiveDeepArr">Update</span>
  </div>
</template>

At this point the page looks like this:

reactive

When we click the Update button respectively, we can see that after the data changes, the content on the view is also updated together:

reactive

4. Is the return value of reactive equal to the source object?

The answer is not equal , because reactive is implemented based on ES2015 Proxy API , and the returned result is a proxy object.

Test code:

 let reactiveSource = { name: 'Chris1993' };
let reactiveData = reactive(reactiveSource);

console.log(reactiveSource === reactiveData);
// false

console.log(reactiveSource);
// {name: 'Chris1993'}

console.log(reactiveData);
// Reactive<{name: 'Chris1993'}>

5. How does TypeScript write ref and reactive parameter types?

When using TypeScript to write ref / reactive parameter types, you can implement specific types according to the ref / reactive interface type:

 function ref<T>(value: T): Ref<T>

function reactive<T extends object>(target: T): UnwrapNestedRefs<T>

Modify the previous example code:

 import { ref } from 'vue'

let refValue = ref<string>('Chris1993');
// refValue 类型为: Ref<string>
let setRefValue = () => {
  refValue.value = 'Hello Chris1993'; // ok!
  refValue.value = 1993; // error!
}

// reactive也类似
let reactiveValue = reactive<{name: string}>({name: 'Chris1993'});

6. What if the ref value is used as a reactive parameter?

What happens when we already have a ref object that needs to be used in a reactive object?

Suppose:

 let name = ref('Chris1993');
let nameReactive = reactive({name})

We can do the following:

 let name = ref('Chris1993');
let nameReactive = reactive({name})
console.log(name.value === nameReactive.name); // true

name.value = 'Hello Chris1993';
console.log(name.value);        // Hello Chris1993
console.log(nameReactive.name); // Hello Chris1993

nameReactive.name = 'Hi Chris1993';
console.log(name.value);        // Hi Chris1993
console.log(nameReactive.name); // Hi Chris1993

This is because reactive will unpack all deep refs and keep ref responsive.

When ref is assigned to the reactive property by assignment, ref is also automatically unpacked:

 let name = ref('Chris1993');
let nameReactive = reactive({})
nameReactive.name = name;

console.log(name.value);        // Chris1993
console.log(nameReactive.name); // Chris1993
console.log(name.value === nameReactive.name); // true

7. Summary

This article mainly introduces the difference between the usage of the two APIs reactive / ref from the perspective of entry, as well as several problems in the use process.

To briefly summarize:

  • reactive Generally used for object/array type data, do not need to use .value ;
  • ref is generally used for data of basic data types. When reading and modifying it in JS, you need to use .value , but not when using it in a template;
  • reactive can modify deep property values and keep responsive;
  • reactive return value is different from the source object;
  • The attribute value of ---123d0168cd7c523dafa08a612f0ce89f reactive can be ref value;
  • ref essence is also reactive , ref(obj) is equivalent to reactive({value: obj}) .

The next article will share the mastery with you, and you are welcome to look forward to it.


pingan8787
3.2k 声望4.1k 粉丝

🌼 前端宝藏小哥哥