首頁 > 軟體

vue3使用reactive包裹陣列正確賦值問題

2023-03-05 14:00:38

使用reactive包裹陣列正確賦值

需求:將介面請求到的列表資料賦值給響應資料arr

const arr = reactive([]);
 
const load = () => {
  const res = [2, 3, 4, 5]; //假設請求介面返回的資料
  // 方法1 失敗,直接賦值丟失了響應性
  // arr = res;
  // 方法2 這樣也是失敗
  // arr.concat(res);
  // 方法3 可以,但是很麻煩
  res.forEach(e => {
    arr.push(e);
  });
};

vue3使用proxy,對於物件和陣列都不能直接整個賦值。

使用方法1能理解,直接賦值給用reactive包裹的物件也不能這麼做。

方法2為什麼不行?

只有push或者根據索引遍歷賦值才可以保留reactive陣列的響應性?

如何方便的將整個陣列拼接到響應式資料上?

提供幾種辦法

const state = reactive({
  arr: []
});
 
state.arr = [1, 2, 3]

或者

const state = ref([])
 
state.value = [1, 2, 3]

或者

const arr = reactive([])
 
arr.push(...[1, 2, 3])

這幾種辦法都可以觸發響應性,推薦第一種

vue3的reactive重新賦值無效

vue3官方的檔案說明

reactive() 返回一個物件的響應式代理

所以 reactive 方法應該作用於一個物件Object,如果要使用陣列,則需要包裝一下:

let list = reactive({
    data: [{id: 01, name: 'XXX'}]
})

或者使用 ref:

let list = ref([{id: 1, name: 'Andy'}])

已下參照原作者的程式碼:

import { reactive, ref } from 'vue'
export default {
  setup() {
    // 需要一個帶預設值的陣列list;
      let list = reactive([{id: 1, name: 'Andy'}])
    
    // 每次觸發事件重置list,把新值放入,此種方式不會觸發檢視更新
    const checkBtn = () => {
      // 此時重置操作 地址指向變成一個新的地址,不會觸發檢視更新
      list = [{id: 1, name: 'Andy'}]
      list.push({id: 2, name: 'Lucy'})
    }
    
    // --------------------------------------------------
    // 正確的重置處理方法如下:使用reactive將陣列包裹到一個物件中
    let list = reactive({
      data: [{id: 1, name: 'Andy'}]
    });
    const checkBtn = () => {
      list.data = [{id: 1, name: 'Andy'}]
      list.data.push({id: 2, name: 'Lucy'})
    }
    // 或者使用ref
    let list = ref([{id: 1, name: 'Andy'}]);
    const checkBtn = () => {
      list.value = [{id: 1, name: 'Andy'}]
      list.value.push({id: 2, name: 'Lucy'})
    }
    return {
      list,
      checkBtn
    }
  },
}

總結

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com