vue3 - When using reactive to define responsive data for list assignment, the view does not update the solution

1. Problem

In Vue 3.0, reactive()when we use the defined responsive data, when it is an array or object, we directly assign a value and find that the data has been modified successfully, but the page is not automatically rendered to the latest data; why is this?

As the official website said, there are some reactives 局限性: ( official description )

insert image description here

2. Reason

The reason is that the reactive function will return a Proxywrapped object, so when we assign a value directly like this: (see the example below)

import {
    
     reactive } from "vue";

let userInfo = reactive([{
    
    name:'Eula'}]) 
console.log(userInfo) // Proxy(Array) 打印出来是一个Proxy对象 当然具备响应式

// 直接后端数据进行赋值
userInfo = [{
    
    name:'优菈'}]
console.log(userInfo)  // [{name:'优菈'}] 可以看出 就是打印出了一个普通的数组 所以不具备响应式

If the value is assigned in this way, the Proxy object will be overwritten, so that the corresponding set and get cannot be triggered, and eventually the responsiveness will be lost;

The above code reactive([{name:'Eula'}]) creates a responsive array, and returns a Proxy-wrapped object userInfoto be stored by a variable, but later I assign an ordinary array (that is, the data returned by the backend) to it. userInfoNote that userInfothis variable has already been stored It is an ordinary array, and of course it is not responsive;

Therefore : for reactivethe created responsive data, you should avoid directly using =numbers for assignment; it will overwrite the responsive type;


3. Solution

1. Encapsulate another layer of data, that is, define the attribute name, and assign this attribute directly when assigning a value later

Encapsulate another layer of data. Note that myRenderListthis attribute is a new attribute used to store list data, but it is a bit more troublesome.

<script setup>
import {
    
     reactive, ref } from "vue";
// 定义响应式 
let list1 = reactive({
    
    myRenderList:[]});

// 请求的数据
let newList1 = [
  {
    
     name: "Eula", age: "18", isActive: false },
  {
    
     name: "Umbra", age: "17", isActive: false },
]

// 更改数据
const setList1 = () => {
    
    
  list1.myRenderList = newList1
}
</script>

3. Use arrays spliceto directly change the original array

It is still reactiveused to define responsive data, but the way to change the data has changed. Using the native method of the array splice()to change the original array is not directly overwritten, so it will not affect the responsive style;

spliceWhen there are three parameters, the array can be modified, the first item is the starting index, the second item is the length, and the third item is the newly inserted element, there can be multiple;

The following code is to delete each item of the previous array, then insert new data , and expand each item newList1using the extension character;...

 list1.splice(0,list1.length,...newList1)

Of course, push()the method can also trigger the response, but it can only add data later. There are also pop, shift, unshift and other methods (not used much)

<script setup>
import {
    
     reactive, ref } from "vue";
// 定义响应式 
let list1 = reactive([]);

// 请求的数据
let newList1 = [
  {
    
     name: "Eula", age: "18", isActive: false },
  {
    
     name: "Umbra", age: "17", isActive: false },
]

// 更改数据
const setList1 = () => {
    
    
  // splice三个参数时 第一项是起始索引  第二项是长度  第三项是新插入的元素,可以有多个
  list1.splice(0,list1.length,...newList1)
}
</script>

3. Use ref to define data

Complex data types can also be refdefined, and the data is responsive; the principle is a bit like the first method, which repackages a layer of value; it must be written every time it is used .value;

ref is actually a layer of packaging for an ordinary value, packaged into an object, and realizes dependency collection and update through its get and set, and its implementation principle is similar to computed;

<script setup>
import {
    
     reactive, ref } from "vue";
// 定义响应式
let list1 = ref([]);

// 请求的数据
let newList1 = [
  {
    
     name: "Eula", age: "18", isActive: false },
  {
    
     name: "Umbra", age: "17", isActive: false },
]

// 更改数据
const setList1 = () => {
    
    
  list1.value = newList1;
}
</script>

Guess you like

Origin blog.csdn.net/qq_43886365/article/details/132190263