該系列是為了讓看過Vue官方文件或學過Vue但是卻不知道怎麼下手去重構現在有的網站而去規畫的系列文章,在這邊整理了許多我自己使用Vue重構很多網站的經驗分享給讀者們。
很多人都會問我說,在寫 vue component 的時候,怎麼樣判斷這個東西要不要拆分成更細 component ? 或是當你接手人家的vue專案的時候,前人留下來的 component 有沒有必要在拆分呢?
大部分的同學都會抱持者在繼續往下寫點東西再來決定的心態,然後就會造成 script、template、style 越寫越長,最後讓你的 component 變成一發不可收拾的地步...
我們先不要管說這個元件是否會共用,單憑你的 component 裡面 script、template、style 加起來大約200 ~ 300行時,其實你就應該要先考慮切你的 component,再來談其他的共用 component 之類的...
我的專案 component 幾乎不會超過300行。
Vue 裡面我把 Component 分成三大類 Page components、Global components、UI components
Page components : 每個獨立頁面的 component,例如像是首頁、關於我們、產品列表等,都是一個獨立的頁面 component。
Global components : 網頁中你會有很多東西是在每個頁面都會出現,例如彈出視窗,或是你的 Header 或 Footer 組件等等這類型的 components。
UI components : 這個囊括了一般我們做元件拆分出來的 component 以及拆分 global components 裡面的內容,我都歸類在 UI components,只是一般頁面上用到的 component 不會被歸類在 global 之中。
為了讓大家更好理解,我們來看看以下設計稿
我大概用以上三種分類的方式切分了一下component
所以我們可以從這張圖很簡單的來清楚明瞭目前切的 component 是屬於哪個類別的。
在我們了解 component 是屬於哪個類別後我們就要對於專案之中 component 的擺放的資料夾開始去切分,我大概簡單的分類一下
|-- src
|-- App.vue
|-- main.js
|-- api
| |-- index.js
|-- assets
| |-- images
| |-- load.gif
| |-- logo.png
|-- components
| |-- Global
| | |-- Alert
| | | |-- index.vue
| | |-- Footer
| | | |-- index.vue
| | |-- Header
| | | |-- index.vue
| | |-- Login
| | |-- index.vue
| |-- Loading
| | |-- CardLoading.vue
| | |-- PageLoading.vue
| |-- Product
| |-- Card.vue
| |-- CardItem.vue
|-- router
| |-- index.js
|-- store
| |-- index.js
|-- view
|-- About.vue
|-- Home.vue
|-- News.vue
|-- Product.vue
我會把 Page components 放入 view 的資料夾中,然後把 Global components、UI components 放入 components 的資料夾,然後把頁面自己的 component 放到該頁面的資料夾裡面再去做細分。
我在載入的組件的時候會像這樣子
<script>
import { ref } from "vue";
import Dynamic from "@/components/Dynamic.vue";
export default {
components: {
Dynamic,
},
setup() {
const isShow = ref(false);
const Open = () => (isShow.value = true);
return { isShow, Open };
},
};
</script>
<template>
<button id="show_btn" @click="Open">click</button>
<Dynamic v-if="isShow" />
</template>
透過 import 載入 Dynamic.vue
import Dynamic from "@/components/Dynamic.vue";
然後再 components 裡面掛載 Dynamic 這個組件,然後放在 template,透過 v-if 來決定是否渲染出來,這樣基本上沒有什麼問題。
就像上面這個範例一樣,我們網頁上面一開始的時候有些component是不想一開始就 show 出來的,所以會透過 v-if 來把它藏起來,不要讓使用者在開發者工具上面找到,但是這樣的載入方式會在網頁一開始載入資源的時候會一起把這個一開始不需要出現的 component 給也打包進來,當你的網頁越來越巨大的時候,這樣子的 component 會造成網站的載入負擔,那要怎麼解決這個問題呢?
我們可以透過 dynamic import 的方式來解決這個問題。
<script>
import { defineAsyncComponent, ref } from "vue";
export default {
components: {
Dynamic: defineAsyncComponent(() => import("@/components/Dynamic.vue")),
},
setup() {
const isShow = ref(false);
const Open = () => (isShow.value = true);
return { isShow, Open };
},
};
</script>
<template>
<button id="show_btn" @click="Open">click</button>
<Dynamic v-if="isShow" />
</template>
我們可以透過import('@/components/Dynamic.vue')
這樣的語法來讓我們的 component 變成動態載入的components,也就是說當我畫面上的 isShow 變成 true 的時候,我的 < Dynamic />
的組件被渲染到網頁上面的時候,它才會載入這個資源,以減少一開始瀏覽器載入網頁資源的效率。
在 Vue3裡面如果你要使用
dynamic import
來載入 component 的話,你要用defineAsyncComponent
這個函式才可以使用dynamic import喔。
參考官方連結: https://v3.vuejs.org/guide/component-dynamic-async.html#async-components
從這邊你就可以知道說使用 dynamic import 可以讓你在需要的時候在載入這個 component 就好了,不需要一開始的時候都載入,至於你要使用哪一種載入方式就依照你的頁面上面的邏輯再來決定你的 import 方式吧!
好啦! 今天介紹如何拆分 component 就到這邊啦,其實拆分 component 每個人的想法或許也都不太一下,我把過往工作上面拆分 component 的經驗分享出來給大家參考一下,希望有幫助到對於拆 component 有障礙的同學,如果有其他的拆分 component 有不一樣想法的朋友也歡迎底下留言一起討論。
Ps. 購買的時候請登入或註冊該平台的會員,然後再使用下面連結進入網站點擊「立即購課」,這樣才可以讓我獲得更多的課程分潤,還可以幫助我完成更多豐富的內容給各位。
我有開設了一堂專門針對Vue3從零開始教學的課程,如果你覺得不錯的話,可以購買我課程來學習
https://hiskio.com/bundles/9WwPNYRpz?s=tc
那如果對於JS基礎不熟的朋友,我也有開設JS的入門課程,可以參考這個課程
https://hiskio.com/bundles/b9Rovqy7z?s=tc
Mike 的 Youtube 頻道
Mike的medium
MIke 的官方 line 帳號,好友搜尋 @mike_cheng
學到了~ dynamic import
想請問老師 鐵人賽這些內容課程都會講到嗎?
鐵人賽是課程的延伸喔,很多基礎的東西只有在課程裡面有