iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 15
0
自我挑戰組

每天來點 Vue.js 吧系列 第 15

Vue components 組件的抽象概念 ✏︎

tags: Vuejs

組件的抽象概念 ✐

註:下方 component組件 一詞意思相同。

component 在 Vue 中是一個重要的概念,照 Evan You 所說靈感來源於 BraidWeb componentRactive,本身是一種抽象(abstraction),我們可以藉此創造 小型、可 複用 的組件,組成組件樹,進一步構建中、大型應用。

以一個簡單的網頁來說,隨著客戶端的功能越來越齊全,許多服務端的程式碼被移到客戶端中,隨著 javascript 程式碼量的增加並且各自連結不同的 HTMLCSS,單純將檔案以 HTMLCSSJavascript 分離,在複用以及管理上是困難的。

來源:vue 官網,可以看到一拖拉谷的 js

Vue component 概念允許我們將網頁分割成如下方的可複用的 小型 component,每個 component 都包含自己的 HTMLCSSJavaScript(每個 component 有自己的樣式以及功能),我們可以按照需求將網頁分割成多個 component,並且在合適的時機複用他們,藉此我們可以觀察到 component 將網頁抽象成以一塊一塊的小元件為單位。

來源:vue 官網,可以看到元件化後的網站

如何看待關注點分離

按照 官網 所說,component 帶來的「關注點分離」,在現代的 UI 開發中,比起過往將 HTMLCSSJavascript 各自分離在相互交織的管理方式,component 所帶來一個內部耦合 模板CSSJavaScript 的結構在維護性上更高,複用上也更加方便。

組件基礎

Vue 應用在之前幾篇文有提到,會透過一個 根組件 以及可選可嵌套的組件樹組成。

根組件

根組件是一個透過建構式創建的 instance new Vue({}),會傳入一組選項物件,全局註冊、局部註冊的 component 可以在該 instance 作為 自定義 元素使用。

可選、可嵌套組件

每個組件都是可以 複用 的 Vue instance,如何建立一個簡單的組件可以透過全局 API Vue.component('component-name', Vue.extend({option})) 建立,該 option 物件和根組件接收一樣的選項,不同的點在於 el 是根組件特有的選項,選定根組件要掛載的元素,在組件中沒有這個選項。

創建的方式可以透過全局註冊一個組件,這裡我們建立一個自定義的 title <my-title> 組件:

  • 設定 template:會替換 <my-title> 內容為 <h3 style="color: #cfcfcf">{{ word }}</h3>
  • 設定 props:用來接收來自父組件的 data,也就是等等呈現的 title 文字:

接著便可以在根組件中使用該組件 <my-title>

這裡透過剛剛註冊的自定義 prop word,當我們傳遞 titleword attribute 時,該 prop word 便會成為 <my-title> instance 中的 property,藉此我們可以從根組件中傳遞值給 <my-title>,等等會細說 props

最終呈現的樣貌,組件可以呈現父組件傳入的 title

使用注意組件的 data 需要透過函式回傳

當我們在使用組件時,要注意 data 需要是透過 function 回傳的物件,這是由於每個組件的 data 皆需要為 獨立 的,透過 function 回傳物件,每個組件對應的 data 皆是一個物件的獨立拷貝。

若是直接設定 data 為物件,組件複用的時候,由於組件對應的 data 是指向同一個物件,於自組件之間的 data 會互相影響。

下面來看看互相影響帶來的問題:

這裡假設一組按鈕元件,每個元件的 data 指向同一個物件,若是 data 中的次數透過按鈕次數可以加一,指向同一物件時,每個元件 instance 會相互影響:

這通常不是我們預期的,所以 Vue 強制了元件的 data 必須是一個由 function 返回的物件。

如下,元件 instance 不會相互影響:

就結論來說,要記得之所以使用 function 返回的物件作為 data,是為了使每個元件 instance 所對應的 data 皆為相互獨立的拷貝,不會互相影響。

組件的全域註冊、局部註冊

剛剛看過了如何在根組件中使用組件後,接著看組件的註冊,組件之所以能夠作為 自定義 元素,在根組件中使用,首先該組件得要被 註冊,這樣組件才能夠被 Vue 辨識,我們才能在根組件模板中使用該 自定義 元素,組件的註冊分成兩種:全局註冊、局部註冊:

全局註冊

組件的全局註冊透過 Vue.component('conponent-name', {}) 創建,透過該方法註冊的組件可以使用在任何的組件中,包含其他的組件、根組件:

一般來說,全局註冊會使用在常常需要在各個元件中使用的基本組件。

局部註冊

說到局部註冊,假如有使用 vue cli 的捧油應該比較常見到局部註冊,比起全局註冊,局部註冊能保障沒有使用一個組件時,該組件不會被 webpack 構建在最終結果,全局註冊組件則是一定會被包含在最終結果中,即使已經沒有使用該全局註冊組件了,仍會增加用戶下載 JavaScript 量的增加。

局部註冊會先定義好組件:

接著在需要用到該局部註冊的組件中,定義該局部註冊組件,也就是 vue cli 常見的組件局部註冊,這之後便可以在此使用此局部註冊組件,模板也能使用其自定義元素。

要記得組件透過局部註冊,無法在其他子組件、非局部註冊組件中使用。這時候,便需要再次局部註冊在想使用的位置。

結語

這次介紹了有關組件的註冊、概念,我們明天見~


若是文中有任何錯誤、錯字、想討論的內容,歡迎各位大大不吝鞭笞指正、交流分享,筆者不慎感激 ✦ ✦ ✦

▶︎ 筆者 github:https://github.com/YUN-RU-TSENG
▶︎ 老王賣瓜之筆者另一篇鐵人:每天來點 CSS Specification

▶︎ 倘若不斷向深處扎根,似乎就能茁壯成長 - RM


參考資料:

  1. Vuejs.org 2.x
  2. Evan You - Inside Vue Components - Laracon EU 2017 - YouTube
  3. Single File Components — Vue.js

上一篇
Vue 雙向數據綁定的語法糖 v-model ✔︎
下一篇
Vue component 父組件向子組件傳遞數據的方法 - Prop(上)
系列文
每天來點 Vue.js 吧30

尚未有邦友留言

立即登入留言