vue3中獲取proxy原始對(duì)象的問(wèn)題

項(xiàng)目中遇到如下問(wèn)題

  1. 在usePassengers先將數(shù)組arr通過(guò)ref響應(yīng)式化
 // 用戶(hù)的數(shù)據(jù)
 const data = [
    { id: 1, name: 'a' },
    { id: 2, name: 'b' },
    { id: 3, name: 'c' },
    { id: 4, name: 'd' }
  ]
// 此處做響應(yīng)化
const passengers = ref(data)
  1. 在組件中,需要用到passengers的數(shù)據(jù)作為復(fù)選框的值,部分代碼如下
const passengersChecked = ref(new Set(unref(passengers)))
  1. 在頁(yè)面操作后,用戶(hù)提交,開(kāi)始組裝報(bào)文
const passengersCheckedValue = toRaw(unref(passengersChecked))
  1. 發(fā)現(xiàn)passengersCheckedValue<Set>里面都是響應(yīng)式對(duì)象
console.log(passengersCheckedValue) // Set(4) {Proxy, Proxy, Proxy, Proxy}

原因

  1. Set 構(gòu)造函數(shù) 會(huì)訪問(wèn)數(shù)組Symbol(Symbol.iterator)、length屬性和每一個(gè)key,只要訪問(wèn)了就會(huì)觸發(fā)代理的get陷阱,get陷阱會(huì)對(duì)訪問(wèn)到的值繼續(xù)做響應(yīng)化處理
get陷阱會(huì)對(duì)訪問(wèn)到的屬性的值繼續(xù)響應(yīng)化
  1. 生成的Set中的子元素就是響應(yīng)化后的對(duì)象,而不再原來(lái)的Object。既Set(4) {Proxy, Proxy, Proxy, Proxy}

  2. 然后在對(duì)Set(4) {Proxy, Proxy, Proxy, Proxy}進(jìn)行響應(yīng)式化。此時(shí)的target就是Set(4) {Proxy, Proxy, Proxy, Proxy}

  3. toRaw 只是返回響應(yīng)式對(duì)象的ReactiveFlags.RAW(__v_raw)屬性,為target。

源碼中的toRaw

解決方案

  // 1. 在生成Set的時(shí)候就獲取去響應(yīng)化后的值
  const passengersChecked = ref(new Set(toRaw(unref(passengers))))
  // 2. 使用shallowRef,只跟蹤自己的 .value 更改,但不會(huì)使其值成為響應(yīng)式的。
  const passengers = shallowRef(data)

如下的這些操作也會(huì)造成對(duì)數(shù)組屬性的訪問(wèn),從而觸發(fā)代理的get陷阱

const passengersChecked = [...passengers]
// 同 new Set(passengers)
// 屬性訪問(wèn)順序 Symbol(Symbol.iterator) length 0 length 1 length 2 length 3

const passengersChecked = Object.entries(passengers)
// 屬性訪問(wèn)順序 0 1 2 3

const passengersChecked = Object.values(passengers)
// 屬性訪問(wèn)順序 0 1 2 3
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容