升級Vue3後,讓人最腦殼疼的應該是新的Compostion API語法,他的難點不是語法,而是他提供了全新的組織程式碼的思維方式。
我剛從Vue2轉到Vue3時,程式碼都嚴格的遵循Compostion API寫法,但是發現比Option API寫法維護性更差。
踩過的坑
1、按技術型別劃分程式碼
在日常開發中,前端一般會收到互動稿或設計稿後開始佈局,然後編寫邏輯程式碼。在Vue2中,通常做法是響應資料放到
data
、邏輯方法放到
methods
,這樣的做法非常方便,也讓我們很容易組織程式碼。
當使用vue3的Compostion API時,如果還是用Vue2的形式組織程式碼,這不但不會提升程式碼質量,反而
因為缺乏約束
而降低可讀性。
我在github隨便找了一段程式碼,你覺得這段程式碼比Vue2簡潔嗎?
export
default
{
setup
()
{
const
state
=
reactive
({
message
:
‘’
,
msgList
:
[]
})
const
router
=
useRouter
()
let
username
=
‘’
onMounted
(()
=>
{
username
=
localStorage
。
getItem
(
‘username’
)
if
(
!
username
)
{
router
。
push
(
‘/login’
)
return
}
})
const
onSendMessage
=
()
=>
{
const
{
message
}
=
state
if
(
!
message
。
trim
()。
length
)
return
state
。
msgList
。
push
({
id
:
new
Date
()。
getTime
(),
user
:
username
,
dateTime
:
new
Date
()。
getTime
(),
message
:
state
。
message
})
state
。
message
=
‘’
}
return
{
。。。
toRefs
(
state
),
onSendMessage
}
}
}
實際上我們過於關注語法層面改變,而忽略官方文件提到一個詞叫:
邏輯關注點!!!!!!
, 邏輯關注點是指表達同一個業務的程式碼內聚到一起,這也是單一職責的指導思想,我們內聚的不應該技術型別,而是業務邏輯,因為觸發程式碼變更的往往是業務需求,因此把相同變更理由的程式碼放在一起,這才不會導致散彈式修改。
2、過於關注邏輯複用
compostion API一個特點是提升邏輯複用,這是沒有錯的,但是當時我有一個錯誤觀點,就是隻有複用的邏輯才應該封裝到hook中。
我們還是回到Vue的官方例子,你會發現他把原來放在一個vue檔案的邏輯拆分到
composables
目錄,目錄下分別定義一個檔案,表示不同的
邏輯關注點
。
官方文件地址:
https://
v3。cn。vuejs。org/guide/c
omposition-api-introduction。html#
什麼是組合式-api
參考程式碼倉庫:
https://
github。com/barnett617/c
omposition-api-demo/blob/292cc63e2e/src/components/UserRepositoriesV3。vue
這個資料夾的程式碼強調的並
不是邏輯複用
,而是
邏輯關注點
分離,這也是compostion API最核心要解決的問題,因為應用生命週期60%時間都是在維護的,而維護性體現在程式碼是否符合單一職責原則,單一職責就是把相同的業務程式碼內聚到一個地方。
所以你不要過於糾結程式碼是否需要複用,應用適當的冗餘反而增加應用的維護性,《架構整潔之道》書中提到:
對於大多數應用,可維護性比可重用性更加重要。
如果你的程式碼真的具有很高的複用性,那可以提升到專案外層目錄,封裝到獨立的hook檔案。
尤雨溪的看法
compostion API在提案的時候,就有很多人持有不同意見,有反對有支援,實際上都沒有錯,只是大家碰到的場景不同而導致不同觀點。我透過閱讀compostion API的RFC,找到了作者對一些問題的解答,整理了一些關鍵問題,內容不是完全翻譯,完整內容建議檢視原文。
原文地址
https://
github。com/vuejs/rfcs/i
ssues/55
問題一:compostion api根本沒有解決任何問題,只是追逐新玩意的東西
尤雨溪:
不同意這個觀點。Vue最開始很小,但是現在被廣泛應用到不同級別複雜度的業務領域,有些可以基於option API很輕鬆處理,但是有些不可以。例如下面的場景:
有很多邏輯的大型元件(數百行)
在多個元件可複用的邏輯
對於問題1,你需要把每個邏輯拆分到不同選項,例如,一段邏輯需要一些響應資料,一個計算屬性,一些監聽屬性還有方法。你去了解這段邏輯時,需要不斷上下移動閱讀,雖然你知道一些屬性是什麼型別,但是你並不知道他具體的作用。當一個元件包含多個邏輯,情況就更糟糕了。如果用新的API,可以將資料和邏輯組合在一起,最重要的是,你可以
乾淨的把這些邏輯提取到一個函式,甚至一個單獨的檔案中。
問題二:使用新API導致邏輯分散到不同地方,違背"關注點分離"
尤雨溪:
這個問題和專案檔案組織方式問題類似。我們很多人都同意按檔案型別組織(佈局放HTML,樣式CSS,邏輯JS)並不是正確的方式,因為強制把相關程式碼分割到三個檔案,只是給人一種“關注點分離”的錯覺。這裡的關鍵是“關注點”不是由檔案型別定義。相反,我們大多數選擇以
功能或者職責
來組織檔案,
這正是人們喜歡Vue單檔案元件的原因
。SFC就是按功能組織程式碼的方法,但諷刺的是當首次引入SFC時,許多人也是拒絕的,認為它違反了關注點分離。
問題三:新的語法讓Vue失去簡單性,導致"義大利麵條式程式碼"的出現,降低專案維護性。
尤雨溪:
正好相反,新的API就是為了提高專案長期維護性的。
如果我們檢視任何javascript專案,都會從入口檔案開始閱讀,該檔案的本質是你的應用啟動時被隱式呼叫的“main”函式。如果只有一個函式入口,會導致義大利麵條程式碼,那所有的js專案都是義大利麵條程式碼。顯然不是的,因為開發人員透過程式碼模組化或者較小的函式來組織程式碼。
另外,我同意新的API理論上會降低程式碼質量的最低門檻。但是我們可以使用以往防止程式碼變成義大利麵條的手段緩解這種情況。另一方面,新的API可以提升程式碼質量的最高上限,相比option api,你可以重構為質量更高的程式碼。而且,基於Option api 你還得解決類似mixins的問題。
很多人認為“Vue失去簡單性”,實際上只是失去元件內程式碼型別檢查能力(就是你不知道一個變數時data、method、還是computed)。但是用新的API,實現一個型別檢測器也是非常容易實現以前的特性的。也就是說,你不應該被option api限制思維,而更多關注邏輯內聚問題。
總結
上面只是節選了RFC討論的幾個小問題,如果你對新API還有其他疑問,建議去github閱讀原文,原文討論了非常多問題,我就不一一總結了。
但是從討論的內容和我實戰的經驗,用新的API,一定要注意轉變程式碼組織思維,記住一個詞
“邏輯關注點”
。
原作者姓名:蟹老闆愛寫程式碼
原出處:掘金
原文連結:不要再用vue2的思維寫vue3了