單頁(yè)面網(wǎng)站復(fù)制南寧seo主管
在vue3中,我們定義響應(yīng)式數(shù)據(jù)無(wú)非是ref和reactive。
但是有的小伙伴會(huì)踩雷!導(dǎo)致定義的響應(yīng)式丟失的問(wèn)題。
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ò)!!!
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ò)!!!
了解響應(yīng)式
1.ref 定義數(shù)據(jù)(包括對(duì)象)時(shí),都會(huì)變成 RefImpl(Ref 引用對(duì)象) 類的實(shí)例,無(wú)論是修改還是重新賦值都會(huì)調(diào)用 setter,都會(huì)經(jīng)過(guò) reactive 方法處理為響應(yīng)式對(duì)象。
2.但是 reactive 定義數(shù)據(jù)(必須是對(duì)象),是直接調(diào)用 reactive 方法處理成響應(yīng)式對(duì)象。如果重新賦值,就會(huì)丟失原來(lái)響應(yīng)式對(duì)象的引用地址,變成一個(gè)新的引用地址,這個(gè)新的引用地址指向的對(duì)象是沒(méi)有經(jīng)過(guò) reactive 方法處理的,所以是一個(gè)普通對(duì)象,而不是響應(yīng)式對(duì)象。解構(gòu)同理。
避坑辦法:
-
避開(kāi)直接賦值和結(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
-
簡(jiǎn)單數(shù)據(jù)類型使用ref()來(lái)進(jìn)行定義。
拔高:TS對(duì)reactive里對(duì)象進(jìn)行限制
上面那種情況是沒(méi)在TS限制的情況下我們解決的,但是有TS用戶就有疑問(wèn)了,這樣我在reactive內(nèi)部再定義一個(gè)對(duì)象,就失去了對(duì)userData的類型限制了,怎么辦呢?
答案:寫(xiě)類!!!!!!!!!!!!!!!!!!!
下面我們就來(lái)研究一下:
1.我們最開(kāi)始會(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)知道不能這樣寫(xiě)了,會(huì)丟失響應(yīng)式。(xxx達(dá)咩)
//2.這時(shí)聰明的你可能會(huì)這樣
data.name=res.data.name;
data.age=res.data.age;//PS:
//問(wèn)題一:賦值太麻煩
//這樣確實(shí)可以不損壞響應(yīng)式,但是如果我說(shuō)你這里面不僅僅有name和age呢,而是有很多很多,那咋辦?//問(wèn)題二:無(wú)法對(duì)userData做類型限制
//你可能又想這樣:
let data=reactive({userData:{}
})
這樣寫(xiě),我們?cè)趺茨軐?duì)userData做類型限制呢?
實(shí)現(xiàn):分開(kāi)寫(xiě)類!!!!!!!!!!!(重點(diǎn)來(lái)啦)
1.單獨(dú)拿出來(lái)一個(gè)ts文件,比如user.ts
//1.定義限制userData的接口
export interface dataRule{name:string,age:number
}//寫(xiě)類
export class data{//定義userData并且做TS限制和賦初始值userData:dataRule={name:"",age:""}
}
在對(duì)應(yīng)的.vue文件中引入該類。
//1.引入剛寫(xiě)好ts類文件
import {dataRule,data} from "@/type/user.ts"//2.重點(diǎn)來(lái)了,我實(shí)例化出來(lái)data,然后用一個(gè)變量User接收。
let User=reactive(new data());/*
//實(shí)例化出來(lái)以后相當(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é)語(yǔ):
在前端的道路上,我們就是要不斷地保持學(xué)習(xí),然后逐漸的變強(qiáng)大,沉淀自己,我們頂峰相見(jiàn)。
--Yan