您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Vue3中ref與reactive的介紹和拓展”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Vue3中ref與reactive的介紹和拓展”吧!
死死記?。簉ef本質(zhì)也是reactive,ref(obj)等價于reactive({value: obj})
vue3中實現(xiàn)響應(yīng)式數(shù)據(jù)的方法是就是使用ref和reactive,所謂響應(yīng)式就是界面和數(shù)據(jù)同步,能實現(xiàn)實時更新
vue2中響應(yīng)式是通過defineProperty實現(xiàn)的,vue3中是通過ES6的Proxy來實現(xiàn)的
reactive的參數(shù)必須是一個對象,包括json數(shù)據(jù)和數(shù)組都可以,否則不具有響應(yīng)式
如果給reactive傳遞了其他對象(如時間對象),默認情況下修改對象界面不會自動更新,如果想更新,可以通過給對象重新賦值來解決
既然有了reactive,為何還要ref呢?當我們只想讓某個變量實現(xiàn)響應(yīng)式的時候,采用reactive就會比較麻煩,因此vue3提供了ref方法進行簡單值的監(jiān)聽,但并不是說ref只能傳入簡單值,他的底層是reactive,所以reactive有的,他都有。還是那句老話:
死死記住:ref本質(zhì)也是reactive,ref(obj)等價于reactive({value: obj})
在vue中使用ref的值,不用通過.value獲取
在js中使用ref的值,必須通過.value獲取
遞歸監(jiān)聽和非遞歸監(jiān)聽
ref和reactive都屬于遞歸監(jiān)聽,也就是數(shù)據(jù)的每一層都是響應(yīng)式的,如果數(shù)據(jù)量比較大,非常消耗性能,非遞歸監(jiān)聽只會監(jiān)聽數(shù)據(jù)的第一層。
ref定義的數(shù)據(jù)每一層都是響應(yīng)式數(shù)據(jù)
shallowRef定義的數(shù)據(jù),只有第一層是響應(yīng)式的,即只有在更改.value的時候才能實現(xiàn)響應(yīng)式
let age = ref({ a: '1', f: { b: '2', s:{ c: '3' } } }) //打印各層數(shù)據(jù) 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' } } }) //打印各層數(shù)據(jù) console.log(age); console.log(age.value); console.log(age.value.f); console.log(age.value.f.s);
使用shallowRef后,可以通過triggerRef()方法主動更新界面,實現(xiàn)界面刷新
function doSome(){ age.value.f.s.c = 'c'; //主動更新界面 triggerRef(age); }
注意:shallowReactive沒有類似triggerRef()的方法
toRaw的出現(xiàn)是解決什么問題呢?
有些時候我們不希望數(shù)據(jù)進行響應(yīng)式實時更新,可以通過toRaw獲取ref或reactive引用的原始數(shù)據(jù),通過修改原始數(shù)據(jù),不會造成界面的更新,只有通過修改ref和reactive包裝后的數(shù)據(jù)時才會發(fā)生界面響應(yīng)式變化。
let obj1 = {...}; //state和obj1是引用關(guān)系,state的本質(zhì)是一個Proxy對象,其中引用了obj1 let state = reactive(obj1); //通過toRaw方法獲取到原始數(shù)據(jù),其實是獲取到obj1的內(nèi)存地址,obj2和obj1是完全相等的 let obj2 = toRaw(state) console.log(obj1 === obj2);//true
有些同學會問,那直接使用obj1來修改數(shù)據(jù)不就行了嗎?可關(guān)鍵是我們在使用reactive定義數(shù)據(jù)時一般不會先定義一個obj,再將他傳給reactive,都是直接在reactive中寫數(shù)據(jù)的。
與toRaw不同,markRaw包裝后的數(shù)據(jù)永遠不會被追蹤!
暫時沒發(fā)現(xiàn)有什么用處(手動狗頭)
let obj1 = {name: "lijing", age: 18} let obj2 = markRaw(obj1); //此時reactive包裝的數(shù)據(jù)雖然是響應(yīng)式對象,但是不會被跟蹤,也不會產(chǎn)生效應(yīng)式效果 let state1 = reactive(obj2) console.log(obj1 === obj2);//true
ref和toRef都是用來構(gòu)造響應(yīng)式數(shù)據(jù),兩者有什么區(qū)別呢,看兩個例子
復(fù)制,修改響應(yīng)式數(shù)據(jù)不會影響以前的數(shù)據(jù),數(shù)據(jù)發(fā)生改變界面就會自動更新
轉(zhuǎn)換后的是一個RefImpl類型
可以看到,使用ref對一個對象的某個簡單數(shù)據(jù)類型屬性進行響應(yīng)式改造后,通過修改響應(yīng)式數(shù)據(jù)不會影響到原始數(shù)據(jù),如上圖中,通過state1修改值后,obj1中的a屬性值沒有發(fā)生變化。這里有個注意點:修改的這個屬性必須是簡單數(shù)據(jù)類型,一個具體的值,不能是引用,如果該屬性也是一個對象,則會影響,因為對象--->引用!
例如上面例子中,如果傳入state1的是obj1.f,則情況完全不同
//等價于let state1 = ref({b: '2',s: {c: '3'}}) // 又等價于--->let state1 = reactive({value: {....}}}) let state1 = ref(obj1.f);
如果使用toRef來轉(zhuǎn)換,則修改響應(yīng)式數(shù)據(jù)會影響到原始數(shù)據(jù),數(shù)據(jù)發(fā)生改變,但是界面不會自動更新
轉(zhuǎn)換后的是一個ObjectRefImpl類型
ref類似深拷貝,toref類似淺拷貝
遍歷對象中的所有屬性,將其變?yōu)轫憫?yīng)式數(shù)據(jù),這是因為toRef只能傳一個key,toRefs所達到的效果與toRef一樣
tips:目前用的最多的還是ref和reactive,其他東西一般是后期用來改善性能使用的。
到此,相信大家對“Vue3中ref與reactive的介紹和拓展”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。