vue3使用reactive包裹數組正確賦值問題

使用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
    }
  },
}

總結

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: