ts watch路由 参数变化_TypeScript基础(六):TS 在 Vue 中的用法,data,生命周期,methods,computed,props,watch,$emit...
其實(shí) ts 在?vue 的環(huán)境下,我們經(jīng)常用的一個(gè)東西就是上一篇博客講的裝飾器。
裝飾器一般情況下有三種用途:
1,裝飾整個(gè)類。
2,裝飾某一個(gè)方法。
3,裝飾某一個(gè)屬性。
而這三種用途對(duì) vue 來說,都是很重要的。
其實(shí)我們已經(jīng)認(rèn)識(shí)了第一種裝飾器,就是我們平時(shí)最常用的:
import?{?Component }?from?"vue-property-decorator";
Component 裝飾器在目前的 Vue 版本里面是必須的。
就是說,就算你用 class 的寫法,你也必須得加這個(gè) Component。
然后我們將 App.vue 里面的東西清空,讓我們自己來寫。
首先第一件事,我們要在 script 標(biāo)簽上面加上?lang="ts"。
然后,第二件事,就需要引裝飾器:
需要注意的是:Component 必須裝飾在 class 上,否則它沒有辦法作為一個(gè)組件類存在。
然后現(xiàn)在有個(gè)問題,我們需要明確,就是這里的 Vue 它到底是什么?
首先,我們可以像以前那么寫,直接從 vue 庫里面引入。
然后,我們也可以在 decorator 里面去引一個(gè) vue。
可以看到,兩種寫法都不會(huì)報(bào)錯(cuò),也都能出來。
那么這兩個(gè) Vue 到底有什么區(qū)別呢?
其實(shí) decorator 它這里的 Vue 存在的價(jià)值,就是可以讓我們少引一個(gè)庫。
等于說,它替我們?cè)谶@個(gè) Vue 給引進(jìn)來了,這樣我們就可以少寫一個(gè) import。
所以它這里的 Vue 其實(shí)并不是一個(gè)真正意義上的裝飾器,它就是普通的 Vue。
然后我們知道了,所謂“裝飾器” 里面的 Vue,其實(shí)就是 Vue。我們引哪個(gè)都行,它只給提供給我們一個(gè)快捷的寫法而已。
接下來,我們就真正去把一個(gè)普通的 Component 寫成 class 的形式。
data 里面的東西,可以全都寫成 成員屬性。
生命周期 和 methods 里面的東西,可以全都寫成 成員方法。
computed?里面的東西,一律寫成訪問器方法,也就是 get / set。
props 對(duì)應(yīng)的是屬性修飾器 @Prop。
我們先來看下原先的寫法,方便做一個(gè)對(duì)比。
創(chuàng)建一個(gè)子組件 Cmp,然后在 App 里面引入。
這里需要注意的一點(diǎn)是,組件之間的引用,還是需要借助裝飾器 @Component。
這是因?yàn)橛却蟠蟛]有提供方法來寫 components。
所以?components 只能放在裝飾器里面。
然后我們?cè)谟?class 的形式寫出 props:
寫完之后我們會(huì)發(fā)現(xiàn),瀏覽器報(bào)錯(cuò)了:
它說,你要避免去給屬性賦值。
簡(jiǎn)單來說,子組件 Cmp 中的 a 并不是一個(gè)普通的屬性。
這里的 a 是父級(jí)傳給它的 props。
所以我們不能給它初始化的時(shí)候賦值。
去掉賦值,就不會(huì)報(bào)錯(cuò)了。
但是你仔細(xì)看, private a 的下面有一個(gè)小紅線,說明還是有問題的。
別急,先留個(gè)印象,我們繼續(xù)往下看。
那么我們?cè)趺慈ハ拗?props 的類型呢?有兩種寫法。
@Component 里面,就是我們?cè)瓉淼膶懛ā?/p>
寫在 @Component 里面,和寫在 @Prop 里面,兩種效果是等同的。
那我們可以在 private a 后面加嗎?
我們傳的是一個(gè)數(shù)字,但我們限制的類型是?string。
但是瀏覽器沒有報(bào)錯(cuò),也沒其他的反應(yīng)。
其實(shí)它報(bào)錯(cuò)了,只不過是在后臺(tái)報(bào)的,還記得上面的那個(gè)小紅線嗎?
這個(gè)報(bào)錯(cuò)的意思是,你的 a 沒有初始值。
好的,那我們重新再加上初始值。
這時(shí)候,后臺(tái)是不報(bào)錯(cuò)了,但是前臺(tái)又報(bào)錯(cuò)了,就是我們最開始遇到的第一個(gè)問題。
因?yàn)閍 是父級(jí)傳給它的 props。所以我們不能給它初始化的時(shí)候賦值。
那么問題就來了:
加了初始值,前臺(tái)報(bào)錯(cuò)。
不加初始值,后臺(tái)報(bào)錯(cuò)。
那你要我怎么做嘛?
其實(shí)在 ts 里面有一個(gè)東西可以幫助我們來解決這個(gè)問題。就是 !?符號(hào)。
那么加上 ! 符號(hào)的意思是什么呢?
意思就是,我知道這個(gè) a 沒有初始化,沒關(guān)系,你先放我過去,我以后會(huì)初始化它的。
所以 ! 這個(gè)標(biāo)志,是用來告訴 ts,我這個(gè)東西以后一定會(huì)賦值的,你就不要報(bào)錯(cuò)了。
問題解決了,那么我們繼續(xù)。其實(shí)我個(gè)人是建議兩個(gè) number 都加上的。
@Prop(Number) 其實(shí)是 Vue 來做的一個(gè)檢查。簡(jiǎn)單來說,如果你給的參數(shù)不對(duì),Vue 會(huì)報(bào)錯(cuò)。
private a: number 這個(gè)是屬于 Vue 那邊已經(jīng)放它過來了,然后到了真正給它去賦值的階段,ts 還要再檢查一遍。
所以個(gè)人建議,2 個(gè)都加上比較保險(xiǎn)。
然后因?yàn)?props 有時(shí)候會(huì)比較多,所以我們一般都是不換行來寫:
那么如果這個(gè) a 既可能是數(shù)字,也可能是字符串呢?
@Prop([Number, String]) 這個(gè)數(shù)組,就是我能接受的類型的數(shù)組。
number | string 這個(gè)是 ts 里面的語法,聯(lián)合類型。
那如果我們還需要默認(rèn)值和驗(yàn)證函數(shù)呢?
其實(shí)和原先的寫法是一樣的,我們可以直接寫一個(gè) json 進(jìn)去。
所以,@Prop 其實(shí)就是把原來寫在 @Component 里面的東西給拆出來了而已。
@Prop 里面還需要注意的一點(diǎn)是:大小寫。
后面的 number 大寫小寫都行,不會(huì)報(bào)錯(cuò)。
這是因?yàn)?number 是 ts 的內(nèi)置類型,基本類型。Number 是 js 里面的一個(gè) class。
所以它們差不多是等同的。
但是,在@Prop 里面只能大寫!小寫就會(huì)報(bào)錯(cuò)。
這是因?yàn)?number 在 ts 里面,它不是一個(gè)東西,它是一個(gè)類型。
前面我們有說過,裝飾器它本質(zhì)上就是一個(gè)函數(shù),@Prop(number) 相當(dāng)于在給函數(shù)傳參。
我們可以傳一個(gè)數(shù)作為參數(shù),也可以傳一個(gè)類作為參數(shù),都沒問題。
但是我們不能傳一個(gè)類型作為參數(shù)。
泛型才可以將類型作為參數(shù)傳進(jìn)去,但是函數(shù)不行。
watch 對(duì)應(yīng)的是方法修飾器 @Watch 。
首先,我們引入 Watch 這個(gè)裝飾器。
@Watch('num') 的意思,就是我要監(jiān)聽變量 num。
然后下面聲明的?numChange 方法,就是當(dāng) num 改變了,就會(huì)觸發(fā)這個(gè)方法。
那么,以前的寫法里面,還有開始就先執(zhí)行一次的 immediate,和深度監(jiān)聽 deep。
那么在 class 里面怎么寫呢?
直接在 @Watch 里面加參數(shù)就可以了。
其實(shí)這種寫法的 watch 特別適合我們?nèi)ト?shù)據(jù)。
上圖中,@Watch 可以直接這樣累加的寫進(jìn)來,是很方便的。
當(dāng) filters 變了的時(shí)候,觸發(fā)一次 reloadDate 方法。
當(dāng) page 變了的時(shí)候,觸發(fā)一次 reloadDate 方法。
所以 @Watch 可以同時(shí)監(jiān)聽多種東西,這一點(diǎn)是非常實(shí)用的。
并且我們聲明了 reloadDate 這個(gè)方法,它本身也可以在其他位置用。
因?yàn)樗旧砭褪且粋€(gè)普通的方法而已,只不過我們?cè)谒厦婕恿藘蓚€(gè)裝飾器而已。
所以現(xiàn)在的 @Watch 比以前寫法的 watch 要方便很多。尤其是數(shù)據(jù)獲取這一塊。
$emit 對(duì)應(yīng)的 @Emit 事件傳遞
其實(shí)這個(gè)并不常用,也不實(shí)用。
我們還是先用原來的寫一遍,來做個(gè)對(duì)比。
比如,現(xiàn)在子組件 Cmp 有一個(gè)按鈕,點(diǎn)擊的時(shí)候,執(zhí)行 fn 函數(shù),并且 $emit 給父級(jí)。
那么當(dāng)我們點(diǎn)擊這個(gè)按鈕的時(shí)候:
其實(shí)就是子組件 Cmp 自己在處理?fn 這個(gè)事件的同時(shí),還順便把這個(gè)事件傳遞給父級(jí) App 了。
$emit 在 class 里面的寫法就很方便了:
我們先注釋掉 $emit。然后引入 Emit,直接放到 fn 上面。
這里需要說一點(diǎn),除了 @Component 以外的裝飾器,全都需要帶上括號(hào)。
其實(shí)說白了,@Emit 的本質(zhì)就是在方法執(zhí)行結(jié)束之后替你去做一個(gè) $emit,并且默認(rèn)的事件名,就是你的方法名。
比如,我現(xiàn)在將事件名改為 xyz:
所以,有了 @Emit 這個(gè)裝飾器之后,就不需要你手動(dòng)的去寫 $emit 了,它會(huì)自動(dòng)的幫你去做傳遞。
但是我們項(xiàng)目中如果真的需要用到事件傳遞的時(shí)候,其實(shí)都還是 $emit 這種寫法。
因?yàn)檎f實(shí)話,@Emit 這個(gè)裝飾器有點(diǎn)不夠靈活,因?yàn)樗潜厝话l(fā)送的。
但是我們?cè)陧?xiàng)目中的實(shí)際開發(fā),很多邏輯都是需要做過判斷之后,在決定發(fā)不發(fā)。
也就是有的時(shí)候需要發(fā),有的時(shí)候不需要發(fā)。
但是用了 @Emit 之后,就必然會(huì)發(fā)送,所以我們基本不會(huì)用到。
總結(jié)
以上是生活随笔為你收集整理的ts watch路由 参数变化_TypeScript基础(六):TS 在 Vue 中的用法,data,生命周期,methods,computed,props,watch,$emit...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【君义精讲】排序算法
- 下一篇: html5倒计时秒杀怎么做,vue 设