錯誤示範:
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); }); };
錯誤原因:
reactive聲明的響應式對象被 arr 代理,操作代理對象需要有代理對象的前綴,直接覆蓋會丟失響應式。也就是說,vue3 使用proxy
,對於對象和數組都不能直接整個賦值。
ref 定義數據(包括對象)時,都會變成 RefImpl(Ref 引用對象) 類的實例,無論是修改還是重新賦值都會調用 setter,都會經過 reactive 方法處理爲響應式對象。但是 reactive 定義數據(必須是對象),是直接調用 reactive 方法處理成響應式對象。如果重新賦值,就會丟失原來響應式對象的引用地址,變成一個新的引用地址,這個新的引用地址指向的對象是沒有經過 reactive 方法處理的,所以是一個普通對象,而不是響應式對象。
實現方案:
// 方案1: 使用ref函數 const state = ref([]) state.value = [1, 2, 3] // 方案2: 使用數組的push方法 const arr = reactive([]) arr.push(...[1, 2, 3])