Vue 元件基礎
在 Vue 中一直有一個論述,叫做:“Everything is components”(一切皆元件)。可見元件在 Vue 開發中舉足輕重的地位。那麼元件究竟是什麼呢?
我們可以把元件理解爲:同時含有 <template></template> 部分、<style></style> 部分、<script></script> 部分,實現從元素、樣式到邏輯處理的一站式完全功能體。 通常,這個功能體被定義在一個 .vue
檔案中。也就是說,我們可以認爲,一個 .vue
檔案就是一個元件。
例如,一個標準的頁面可以被分爲 header(頭部)、main(主要部分)、sidebar(側邊欄)、footer(尾部)。其中每一個部分,都有自己的元素(HTML)、樣式(Style)和邏輯(JavaScript),所以一個頁面可以就可以被分爲若干元件。同時,這個頁面在 Vue 中也是一個 .vue
檔案,故這個頁面也可以看作是一個大元件。因此,在學習的前期,我們不妨將元件分爲頁面元件 和功能元件 。頁面元件是 Mount 在路由中,顯示一整個頁面的元件,而功能元件則是放到頁面元件中,是頁面的某一部分。
宣告元件
我們明白了元件的概念,自然明白該怎樣去宣告元件。只需要新增一個 .vue
檔案,包含這三個部分,一個元件就被宣告了。
使用元件
一個元件被宣告之後,必須被放到頁面上,才能夠顯示出來。也就是將某個元件放到更大的元件中去。因此,我們需要在更大的元件中去引入並使用這個元件。
首先,我們要在元件的 <script></script>
部分引入該元件:
然後,我們可以在元件的 <template></template>
部分使用該元件:
這樣,這個元件就會被添加到更大的元件中,可以在父元件的相應位置顯示了。
元件 Props
元件的一個重要的特性就是將一個功能的集合體抽離出來。抽離出來的東西具有可復現性。
例如,我們有一個元件,會在很多個頁面中都用到,但是每個頁面中,該元件展示的信息不一樣。那我們該怎麼做呢?難道要定義很多個元件嗎?當然不是。因爲該元件的基本結構都是確定的,只是其中微小的部分有差異。那這種情況下,我們就需要父元件告訴子元件,到底要展示什麼內容,也就是說,需要父元件向子元件中傳送 props(屬性)。
要實現這個過程,需要執行以下步驟:
- 在子元件中定義需要傳入的 props
- 在父元件中傳入這個 prop 的值
渲染結果如下:
上面的例子實現了從父元件向子元件傳送一個 String 類型的 prop 名叫 nihao,我們可以看到,當向子元件傳送不同的 prop 值,子元件渲染到頁面上的內容也不同。
如果我們想要將父元件中的一個 JS 變數作爲 prop 傳入子元件,我們也可以使用模板語法來完成:
這樣子,當 veriable 變數發生改變的時候,傳入子元件的 prop 也相應發生改變。如果你想要將數字或者 Boolean 等類型傳入子元件,就必須使用模板語法纔可以。因爲預設的靜態傳入方式只能向裏面傳送字串。
事件處理
如果說父元件向子元件交流是透過傳送 prop 實現的,那麼子元件如果有內容需要報告給父元件,又該怎麼做呢?是透過一個叫做事件處理的程式來進行的。
完成該過程有兩種辦法,第一種是比較簡單的方法,只能在子元件中某些元素觸發 JS 事件之後,向父元件傳送一些固定的內容。實現過程如下:
使用 $emit()
來向父元件傳送資料。event 是事件的名字。
在父元件中,可以透過事件監聽來處理子元件傳入的資料:
以上表示,一旦有監聽到子元件的 event 事件,就執行 func 函式。
我們也可以在子元件向上傳送事件的過程中向上傳送資料:
event 是事件名稱,1 是要向上傳入的內容。該內容將作爲父元件中 func 函式的引數傳入。
除了這種簡單的方式,我們還可以將 emit 寫在 JS 部分,這樣我們就不必拘泥於按鈕的點擊、輸入框的輸入等等,可以在任何想拋出事件的時候,就將事件拋給父元件。
元件v-model
我們上一節課有講到,v-model
用於模板和資料的雙向綁定。我們也可以在開發元件的時候,爲我們的元件添加上這一屬性。
當我們爲元件添加了這一屬性後,父元件綁定到子元件的這一變數就可以直接在子元件中使用了,就像是在子元件中宣告的一樣。在子元件中改變該變數的值,父元件中也會相應改變。
父元件中可以透過 v-model
綁定一個 JS 變數:
這樣,我們就透過 v-model
,將父元件中 val
這個變數綁定到了子元件中 model
這個變數。也可以說,val
和 model
是同一個變數,只不過在父元件和子元件中分別叫 val
和 model
而已。
在子元件中執行的 update_model()
函式,在改變子元件 model
變數的同時,由於 model
變數和父元件 val
變數互相綁定,故父元件中 val
變數也同步改變。反之亦然。
關於元件 v-model
的其餘內容,包括元件多個 v-model
的實現,請讀者自行查閱 Vue 官方文檔。模式基本相同,在此不再贅述。
插槽(Slot)
還記得我們遙遠遙遠的第一節課上,我和各位有談過一件什麼事情嗎?
單葉標籤和雙葉標籤。
我曾經在課上說過,這兩個詞語是我自己創造出來的,但很應景。所謂的雙葉標籤,兩個標籤葉之間是可以包圍一些東西的,從而可以渲染到頁面上。而單葉標籤由於只有一個標籤葉,所以沒有辦法在其中夾東西。
不知道大家發現了沒有,在之前我們所定義的所有元件,在父元件中使用的時候,幾乎都是單葉元件,儘管元件也可以被寫成雙葉形式:
但是在這種情況下,裏面包圍的任何東西都是不會被顯示和渲染的。
要實現在裏面放東西,並且還能夠渲染到子元件的相應位置,我們就需要用到“插槽”這個東西。在子元件需要渲染的地方加上一個插槽,就可以引導着雙葉之間的內容渲染到相應的部位了。例如,我們在子元件中可以這樣宣告:
然後在父元件中就可以在雙葉之間添加內容了:
<slot></slot>
關鍵字即爲插槽的標誌,代表着父元件雙葉之間的內容將被替換到這裏。上述內容渲染之後是這樣的:
可以看到,雙葉之間的內容被替換到了子元件中<slot></slot>
的位置。
至於多插槽的配置,還請讀者自行查閱Vue官方文檔,文檔的內容很好理解。
重要的內置元件
在Vue框架中,有幾個元件是Vue官方幫我們寫好的,我們可以直接使用去實現相應的功能。下面筆者將介紹其中兩個使用比較廣泛的元件。
Transition
<Transition>
會在一個元素或元件進入和離開 DOM 時套用動畫。
進入或離開可以由以下的條件之一觸發:
- 由 v-if 觸發的切換
- 由 v-show 觸發的切換
- 由特殊元素
<component>
切換的動態元件 - 改變特殊的 key 屬性
其中,前兩項是我們比較常用的,第三項將在下一個內置元件中詳細介紹,最後一項不是很常見。
下面是官方文檔中提供給我們的用法案例:
下面我們來解釋一下這些 CSS 動畫效果的實現。 總共有 6 個應用於進入與離開過渡效果的 CSS class。
上面這張圖片很好地展示了這個過程。因此,我們就可以在CSS中,將這些狀態或過程的CSS樣式都定義出來,這樣 Transition 元件就會幫我們實現這個過渡的過程。
這是官方文檔的解釋:
-
v-enter-from
:進入動畫的起始狀態。 在元素插入之前添加,在元素插入完成後的下一幀移除。 -
v-enter-active
:進入動畫的生效狀態。 應用於整個進入動畫階段。 在元素插入之前添加,在過渡或動畫完成之後移除。 這個 class 可以用來定義進入動畫的持續時間、延遲與速度曲線類型。 -
v-enter-to
:進入動畫的結束狀態。 在元素插入完成後的下一幀被添加 (也就是 v-enter-from 被移除的同時),在過渡或動畫完成之後移除。 -
v-leave-from
:離開動畫的起始狀態。 在離開過渡效果被觸發時立即添加,在一幀後被移除。 -
v-leave-active
:離開動畫的生效狀態。 應用於整個離開動畫階段。 在離開過渡效果被觸發時立即添加,在過渡或動畫完成之後移除。 這個 class 可以用來定義離開動畫的持續時間、延遲與速度曲線類型。 -
v-leave-to
:離開動畫的結束狀態。 在一個離開動畫被觸發後的下一幀被添加 (也就是 v-leave-from 被移除的同時),在過渡或動畫完成之後移除。
爲過渡效果命名
上面我們套用的動畫,包括我們寫的 CSS,是沒有命名的。如果我們有好幾個需要套用不同動畫的元素,這顯然是不夠的。因此,我們可以把每一個動畫效果命名,然後選擇每一個需要套用動畫的元素使用哪一個動畫效果。
例如,我們需要名叫 “fade” 的一套動畫,我們首先要在 CSS 中,把前面的效果 class 改成:
可以看到,僅僅只是 “v” 換成了需要命名的名字而已。
然後,我們可以在 <Transition>
元件的 name 屬性去套用這個命名:
KeepAlive
要明白這個元件的用處,我們首先要引入動態元件的概念。有些情況下,我們會需要在兩個元件之間互相切換,比如標籤頁。
在這種情況下,我們可以使用 <component>
標籤來代替不同的元件:
其中,activeComponent
是一個 JS 變數,其值是已經引入的子元件的名字或者元件實例。
預設情況下,一個元件實例在被替換掉後會被銷毀。 這會導致它遺失其中所有已變更的狀態-當這個元件再一次被顯示時,會建立一個只帶有初始狀態的新實例。
在切換時建立新的元件實例通常是有意義的,但有些時候,我們的確想要元件能在被「切走」的時候保留它們的狀態。 要解決這個問題,我們可以用 <KeepAlive>
內建元件將這些動態元件包裝起來:
元件庫
元件是功能的集合體,而許許多多這樣的元件放到一起,就形成了元件庫。Vue3 有大量的第三方元件庫,包含了許許多多可以使用的元件。這些元件庫極大拓展了 Vue3 的能力。
國內目前比較流行的元件庫是 Element Plus。