Talking about Vue3: (1) Vue3 Responsive Basics

Table of contents

1. Vue3 Responsive Basics

1. Declare reactive state

2. DOM update timing

3. Deep Responsiveness and Shallow Responsiveness

4. Reactive Proxy vs. Primitive Objects

5. Define responsive variables with ref()


1. Vue3 Responsive Basics

1. Declare reactive state

We can use the reactive() function to create a reactive object or array and if we want to use it, we can setup() define it in the function and return it.

<script>
import { reactive } from "vue";
export default {
  // `setup` 是一个专门用于组合式 API 的特殊钩子函数
  setup() {
    let oneNumber = reactive({ count: 0 });
    function add() {
      oneNumber.count++;
    }
    // 暴露 state 到模板
    return {
      oneNumber,
      add,
    };
  },
};
</script>
<template>
  <button @click="add">
    {
    
    { oneNumber.count }}
  </button>
</template>
<style scoped></style>

It is cumbersome to manually expose a large number of states and methods in  setup() functions, so we can use <script setup> to simplify the code, as follows:

<script setup>
import { reactive } from "vue";
let oneNumber = reactive({ count: 0 });
function add() {
  oneNumber.count++;
}
</script>

<template>
  <button @click="add">
    {
    
    { oneNumber.count }}
  </button>
</template>

2. DOM update timing

When changing the responsive state, the DOM is automatically updated. However, DOM updates are not synchronous . Instead, Vue will buffer them until the "next moment" in the update cycle to ensure that no matter how many state changes you make, each component is only updated once. To wait for a DOM update to complete after a state change, you can use this global API

<script setup>
import { reactive, nextTick } from "vue";
let oneNumber = reactive({ count: 0 });
function add() {
  oneNumber.count++;
  console.log(document.getElementById("addBtn").textContent);
  nextTick(() => {
    // 访问更新后的 DOM
    console.log(document.getElementById("addBtn").textContent);
  });
}
</script>

<template>
  <button @click="add" id="addBtn">
    {
    
    { oneNumber.count }}
  </button>
</template>

Obviously, when executingadd时,访问dom的内容是操作count之前的值,在nextTick之后才为count更新后的值

3. Deep Responsiveness and Shallow Responsiveness

Deep Responsiveness:

In Vue, state is deep reactive by default. This means that changes can be detected even when changing deep objects or arrays.

<script setup>
import { reactive } from "vue";
let oneNumberObj = reactive({
  nested: { count: 0 },
  arr: ["hello", "vue3"],
});

function add() {
  oneNumberObj.nested.count++;
  oneNumberObj.arr[0] = "ts" + oneNumberObj.nested.count;
}
</script>

<template>
  <button @click="add" id="addBtn">
    {
   
   { oneNumberObj.nested.count }}--{
   
   { oneNumberObj.arr[0] }}
  </button>
</template>

Obviously, when executingadd时,count和arr都可以做出相应

Shallow responsiveness:

Only the root-level properties in a shallow reactive object are reactive.

<script setup>
import { reactive,shallowReactive } from "vue";
let oneNumberObjShallow = shallowReactive({
  nested: { count: 0 },
  arr: ["hello", "vue3"],
});
function add() {
  oneNumberObjShallow.nested.count++;
  oneNumberObjShallow.arr[0] = "ts" + oneNumberObjShallow.nested.count;
}
</script>

<template>
  <button @click="add" id="addBtn">
    {
   
   { oneNumberObjShallow.nested.count }}--{
   
   { oneNumberObjShallow.arr[0] }}
  </button>
</template>

Obviously, when executingadd时,count和arr不可以做出相应

4. Reactive Proxy vs. Primitive Objects

reactive() What is returned is a Proxy of the original object, which is not equal to the original object.

Only the proxy object is reactive, changing the original object will not trigger an update. So best practice with Vue's reactive system is  to only use proxy versions of your declared objects

Calling on the same original object  reactive() will always return the same proxy object, while calling on an existing proxy object  reactive() will return itself

as follows:

<script setup>
import { reactive } from "vue";
let oneNumber = { count: 0 };
let proxy = reactive(oneNumber)
function addProxy() {
  proxy.count++;
  console.log(proxy === oneNumber) //false
  console.log(reactive(oneNumber) === proxy) //true
  console.log(reactive(proxy) === proxy) //true

}
</script>

<template>
  <button @click="addProxy">
    {
   
   { proxy.count }}
  </button>
</template>

5.  ref() Define responsive variables with

reactive() is only valid for object types, so we can use ref() to allow us to create reactive types that can use any value type 

ref() Wrap the value of the incoming parameter as a  .value ref object with attributes

When refs are accessed as top-level attributes in templates, they are automatically "unwrapped", so there is no need to use .value

Unlike reactive objects, refs  Map are not unwrapped when accessed as elements of a reactive array or like this native collection type.

as follows:

<script setup>
import { ref,reactive } from 'vue'
const oneNumber = ref(0)
const oneStr = reactive([ref('Vue3')])
function add() {
  oneNumber.value++
}
</script>

<template>
  <button @click="add">
    {
   
   { oneNumber }} <!-- 无需 .value -->
  </button>
  <div>{
   
   { oneStr[0].value }}</div>

</template>

If you have any questions, please comment below and I will answer them for you.

Guess you like

Origin blog.csdn.net/samxiaoguai/article/details/128472892