- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) > web開(kāi)發(fā) > JavaScript >
- Vue3中ref與reactive的詳解與擴展
死死記?。簉ef本質(zhì)也是reactive,ref(obj)等價(jià)于reactive({value: obj})
既然有了reactive,為何還要ref呢?當我們只想讓某個(gè)變量實(shí)現響應式的時(shí)候,采用reactive就會(huì )比較麻煩,因此vue3提供了ref方法進(jìn)行簡(jiǎn)單值的監聽(tīng),但并不是說(shuō)ref只能傳入簡(jiǎn)單值,他的底層是reactive,所以reactive有的,他都有。還是那句老話(huà):
死死記?。簉ef本質(zhì)也是reactive,ref(obj)等價(jià)于reactive({value: obj})
遞歸監聽(tīng)和非遞歸監聽(tīng)
ref和reactive都屬于遞歸監聽(tīng),也就是數據的每一層都是響應式的,如果數據量比較大,非常消耗性能,非遞歸監聽(tīng)只會(huì )監聽(tīng)數據的第一層。
let age = ref({ a: '1', f: { b: '2', s:{ c: '3' } } }) //打印各層數據 console.log(age); console.log(age.value); console.log(age.value.f); console.log(age.value.f.s);
let age = shallowRef({ a: '1', f: { b: '2', s:{ c: '3' } } }) //打印各層數據 console.log(age); console.log(age.value); console.log(age.value.f); console.log(age.value.f.s);
使用shallowRef后,可以通過(guò)triggerRef()方法主動(dòng)更新界面,實(shí)現界面刷新
function doSome(){ age.value.f.s.c = 'c'; //主動(dòng)更新界面 triggerRef(age); }
注意:shallowReactive沒(méi)有類(lèi)似triggerRef()的方法
toRaw的出現是解決什么問(wèn)題呢?
有些時(shí)候我們不希望數據進(jìn)行響應式實(shí)時(shí)更新,可以通過(guò)toRaw獲取ref或reactive引用的原始數據,通過(guò)修改原始數據,不會(huì )造成界面的更新,只有通過(guò)修改ref和reactive包裝后的數據時(shí)才會(huì )發(fā)生界面響應式變化。
let obj1 = {...}; //state和obj1是引用關(guān)系,state的本質(zhì)是一個(gè)Proxy對象,其中引用了obj1 let state = reactive(obj1); //通過(guò)toRaw方法獲取到原始數據,其實(shí)是獲取到obj1的內存地址,obj2和obj1是完全相等的 let obj2 = toRaw(state) console.log(obj1 === obj2);//true
有些同學(xué)會(huì )問(wèn),那直接使用obj1來(lái)修改數據不就行了嗎?可關(guān)鍵是我們在使用reactive定義數據時(shí)一般不會(huì )先定義一個(gè)obj,再將他傳給reactive,都是直接在reactive中寫(xiě)數據的。
與toRaw不同,markRaw包裝后的數據永遠不會(huì )被追蹤!
暫時(shí)沒(méi)發(fā)現有什么用處(手動(dòng)狗頭)
let obj1 = {name: "lijing", age: 18} let obj2 = markRaw(obj1); //此時(shí)reactive包裝的數據雖然是響應式對象,但是不會(huì )被跟蹤,也不會(huì )產(chǎn)生效應式效果 let state1 = reactive(obj2) console.log(obj1 === obj2);//true
ref和toRef都是用來(lái)構造響應式數據,兩者有什么區別呢,看兩個(gè)例子
復制,修改響應式數據不會(huì )影響以前的數據,數據發(fā)生改變界面就會(huì )自動(dòng)更新
轉換后的是一個(gè)RefImpl類(lèi)型
可以看到,使用ref對一個(gè)對象的某個(gè)簡(jiǎn)單數據類(lèi)型屬性進(jìn)行響應式改造后,通過(guò)修改響應式數據不會(huì )影響到原始數據,如上圖中,通過(guò)state1修改值后,obj1中的a屬性值沒(méi)有發(fā)生變化。這里有個(gè)注意點(diǎn):修改的這個(gè)屬性必須是簡(jiǎn)單數據類(lèi)型,一個(gè)具體的值,不能是引用,如果該屬性也是一個(gè)對象,則會(huì )影響,因為對象--->引用!
例如上面例子中,如果傳入state1的是obj1.f,則情況完全不同
//等價(jià)于let state1 = ref({b: '2',s: {c: '3'}}) // 又等價(jià)于--->let state1 = reactive({value: {....}}}) let state1 = ref(obj1.f);
如果使用toRef來(lái)轉換,則修改響應式數據會(huì )影響到原始數據,數據發(fā)生改變,但是界面不會(huì )自動(dòng)更新
轉換后的是一個(gè)ObjectRefImpl類(lèi)型
ref類(lèi)似深拷貝,toref類(lèi)似淺拷貝
遍歷對象中的所有屬性,將其變?yōu)轫憫綌祿?,這是因為toRef只能傳一個(gè)key,toRefs所達到的效果與toRef一樣
tips:目前用的最多的還是ref和reactive,其他東西一般是后期用來(lái)改善性能使用的。
到此這篇關(guān)于Vue3中ref與reactive的文章就介紹到這了,更多相關(guān)Vue3 ref與reactive內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站