Vue3中reactive丟失響應(yīng)式的問題解決(避大坑!)
在vue3中,我們定義響應(yīng)式數(shù)據(jù)無非是ref和reactive。但是有的小伙伴會(huì)踩雷!導(dǎo)致定義的響應(yīng)式丟失的問題。
reactive丟失響應(yīng)式的情況1(直接賦值)
場(chǎng)景: 1.你定義了一個(gè)數(shù)據(jù):let data=reactive({ name:"", age:"" }) 2.然后你請(qǐng)求了接口,賦值給data let res=await getUserApi(); //請(qǐng)求接口 data=res.data; //將返回的結(jié)果賦值給data
大錯(cuò)特錯(cuò)?。。?/p>
reactive丟失響應(yīng)式的情況2(解構(gòu)賦值)
場(chǎng)景: 1.你定義了一個(gè)數(shù)據(jù):let data=reactive({ name:"", age:"" }) 2.然后你解構(gòu)了 let {name}=data; //解構(gòu)賦值
大錯(cuò)特錯(cuò)?。。?/p>
了解響應(yīng)式
1.ref 定義數(shù)據(jù)(包括對(duì)象)時(shí),都會(huì)變成 RefImpl(Ref 引用對(duì)象) 類的實(shí)例,無論是修改還是重新賦值都會(huì)調(diào)用 setter,都會(huì)經(jīng)過 reactive 方法處理為響應(yīng)式對(duì)象。
2.但是 reactive 定義數(shù)據(jù)(必須是對(duì)象),是直接調(diào)用 reactive 方法處理成響應(yīng)式對(duì)象。如果重新賦值,就會(huì)丟失原來響應(yīng)式對(duì)象的引用地址,變成一個(gè)新的引用地址,這個(gè)新的引用地址指向的對(duì)象是沒有經(jīng)過 reactive 方法處理的,所以是一個(gè)普通對(duì)象,而不是響應(yīng)式對(duì)象。解構(gòu)同理。
避坑辦法:
避開直接賦值和結(jié)構(gòu),reactive直接包裹一個(gè)對(duì)象。
let data=reactive({ userData:{} //里面定義一個(gè)對(duì)象,這樣賦值就不會(huì)丟失響應(yīng)式了。 }) //獲取接口數(shù)據(jù) let res=await getUserApi(); //請(qǐng)求接口 data.userData=res.data; //將返回的結(jié)果賦值給data
簡單數(shù)據(jù)類型使用ref()來進(jìn)行定義。
拔高:TS對(duì)reactive里對(duì)象進(jìn)行限制
上面那種情況是沒在TS限制的情況下我們解決的,但是有TS用戶就有疑問了,這樣我在reactive內(nèi)部再定義一個(gè)對(duì)象,就失去了對(duì)userData的類型限制了,怎么辦呢?
答案:寫類?。。。。。。。。。。。。。。。。。?!
下面我們就來研究一下:
1.我們最開始會(huì)可能這樣對(duì)data加上類型限制:
interface dataRule{ name:string, age:number } //定義數(shù)據(jù) let data:dataRule=reactive({ name:"", age:"" }) //但是,當(dāng)獲取接口的時(shí)候 let res=await getUserApi(); //請(qǐng)求接口 //data=res.data; //我們已經(jīng)知道不能這樣寫了,會(huì)丟失響應(yīng)式。(xxx達(dá)咩) //2.這時(shí)聰明的你可能會(huì)這樣 data.name=res.data.name; data.age=res.data.age; //PS: //問題一:賦值太麻煩 //這樣確實(shí)可以不損壞響應(yīng)式,但是如果我說你這里面不僅僅有name和age呢,而是有很多很多,那咋辦? //問題二:無法對(duì)userData做類型限制 //你可能又想這樣: let data=reactive({ userData:{} }) 這樣寫,我們?cè)趺茨軐?duì)userData做類型限制呢?
實(shí)現(xiàn):分開寫類?。。。。。。。。。?!(重點(diǎn)來啦)
1.單獨(dú)拿出來一個(gè)ts文件,比如user.ts
//1.定義限制userData的接口 export interface dataRule{ name:string, age:number } //寫類 export class data{ //定義userData并且做TS限制和賦初始值 userData:dataRule={ name:"", age:"" } }
在對(duì)應(yīng)的.vue文件中引入該類。
//1.引入剛寫好ts類文件 import {dataRule,data} from "@/type/user.ts" //2.重點(diǎn)來了,我實(shí)例化出來data,然后用一個(gè)變量User接收。 let User=reactive(new data()); /* //實(shí)例化出來以后相當(dāng)于這樣的結(jié)構(gòu): User={ userData:{ name:"", age:"" } } */ //3.我們調(diào)用接口 //獲取接口數(shù)據(jù) let res=await getUserApi(); //請(qǐng)求接口 User.userData=res.data; //將返回的結(jié)果賦值給data,這樣也不會(huì)丟失響應(yīng)式,并且userData也受了TS的限制。
結(jié)語:
到此這篇關(guān)于Vue3中reactive丟失響應(yīng)式問題解決的文章就介紹到這了,更多相關(guān)Vue3 reactive丟失響應(yīng)式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue實(shí)現(xiàn)前后端完全分離的項(xiàng)目實(shí)戰(zhàn)
本文主要介紹了Vue實(shí)現(xiàn)前后端完全分離的項(xiàng)目實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08vue實(shí)現(xiàn)移動(dòng)端拖動(dòng)排序
這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)移動(dòng)端拖動(dòng)排序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-08-08Vue包大小優(yōu)化的實(shí)現(xiàn)(從1.72M到94K)
這篇文章主要介紹了Vue包大小優(yōu)化的實(shí)現(xiàn)(從1.72M到94K),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02Vue添加請(qǐng)求攔截器及vue-resource 攔截器使用
這篇文章主要介紹了Vue添加請(qǐng)求攔截器及vue-resource 攔截器使用,需要的朋友可以參考下2017-11-11vue2.6.10+vite2開啟template模板動(dòng)態(tài)編譯的過程
這篇文章主要介紹了vue2.6.10+vite2開啟template模板動(dòng)態(tài)編譯,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02vue面試created中兩次數(shù)據(jù)修改會(huì)觸發(fā)幾次頁面更新詳解
這篇文章主要為大家介紹了vue面試created中兩次數(shù)據(jù)修改會(huì)觸發(fā)幾次頁面更新問題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12