實戰Vue元件和Mixins
特別宣告,本文根據 ofollow,noindex" target="_blank">@Saqueib Ansari 的《 Practical use of Components and Mixins in Vue JS 》一文所整理。
這篇文章主要幫助我們深入的學習Vue的元件和 mixins
,它們幫助你擴充套件基本的HTML元素,用來封裝可重用的程式碼。在較高的層次上,元件是定製的元素,Vue的編譯器附加了行為,而 mixins
為你提供了一個保持程式碼可重用性的方式,從而使你的程式碼保持乾淨和易於維護。
如果你從未接觸過Vue的 mixins
,建議你花點時間先閱讀《 Vue中的 Mixins
》一文。
Vue元件
元件是一段可重用的UI,它封裝了其中的所有行為和功能。比如Chrome的日期輸入框( <input type="date">
)就是瀏覽器提供的一個元件,它會給你一個日曆彈出框來供你選擇日期。你只需要在使用的地方新增一個型別( type
)為 date
的輸入框( input
),即: <input type="date" >
,就可以神奇地獲得所有關於日期的功能。類似地,Vue為你提供了建立自己定製元件的選項。如果你想構建SPA,你可能需要一個根元件,比如 App
( <App>
)元件,它通常充當包裝器,幷包含所有的根級狀態。
建立一個元件
現在讓我們在Vue中建立一個元件,我們將構建一個 Card
元件:
<!-- Card.vue --> <template> <div class="card"> <div class="card-header">Card title</div> <div class="card-body">Card content</div> </div> </template> <!-- App.vue --> <template> <div id="app" class="container"> <Card /> </div> </template> <script> import Card from "./components/Card"; export default { name: "App", components: { Card } }; </script>
這是我們想要的樣子:
沒有什麼特別的,一個簡單的元件需要一個名稱( name
,比如上例中的 Card
)作為元素的標籤和由該標籤渲染的模板( <template>
)。在上面的示例中,使用的是 <Card />
。也有人建議在元件名稱前新增自己的私有字首,這樣做的好處是不是與第三方引入的元件名發生衝突。
向元件傳遞資料
就上面示例而言, Card
元件到目前為止並沒有做任何事,只是顯示了文字中位符,並無法達到定製標題和內容的效果(也就是動態載入資料,更改模板中的內容)。這個時候我們可以給 Card
定製兩個屬性: title
和 body
。在Vue中,元件可以通過 props
接受外部資料,因此在上例的基礎上,定義 title
和 body
來動態接受外部資料。
<!-- Card.vue --> <template> <div class="card mb-3"> <div class="card-header">{{ title }}</div> <div class="card-body">{{ body }}</div> </div> </template> <script> export default { name: "Card", props: ['title', 'body'], data() { return {}; } }; </script> <!-- App.vue --> <template> <div id="app" class="container"> <Card v-for="(item, index) in cardLists" :title="item.title" :body="item.body" :key="index" /> </div> </template> <script> import Card from "./components/Card"; export default { name: "App", components: { Card }, data() { return { cardLists: [ { title: "User Details", body: "Hi, I am Airen from https://www.w3cplus.com" }, { title: "Latest Posts", body: "Components, Directives, Filters and Mixins in Vue JS" } ] }; } }; </script>
正如你所見,在 <Card>
元件上添加了 Props
,因此在模板中可以使用 {{ title }}
和 {{ body }}
給HTML元素傳遞值,從而取替了之前的靜態文字。這樣就可以在呼叫 <Card>
元件的地方,通過 title="some literal string"
或者像示例中一樣通過 :title="titleVar"
繫結一個變數。
這樣一來,我們的元件就可以達到重用的目的。
注,這裡使用了Vue中的一些指令,比如 v-for
和 v-bind
。其中 v-for
用來對資料做遍歷,而 v-bind
用來做屬性的繫結。
建立一個子元件
我們還可以將元件巢狀在另一個元件中。接下來讓我們來建立一個 Follow
元件,它就像一個切換器(關注還是未關注)一樣,用來跟蹤使用者。
在 UserList
元件中,我們從 https://reqres.in
中獲取使用者相關的資訊,然後將它們新增到 users
陣列件,最後通過 v-for
將其遍歷出來。你也可以看到在 UserList
中添加了一個子元件 Follow
,該元件放置在 UserList
元件的使用者名稱下面。因此,你可以將任何元件巢狀在另一個元件中。你可以點選 Follow
按鈕進行狀態切換,那是因為使用 v-on
將 click
事件綁定了一個 toggle
方法,當然,你也可以使用 @click="toggle"
這樣的簡寫方式。在我們的示例中,還在 @click
後面添加了一個字尾 prevent
,用來防止元素預設的事件。在 toggle
方法中,主要做的事件就是用來切換按鈕狀態,用來追蹤狀態已更改。
將資料從子元件傳遞到父元件
Vue自琮釋出子事件系統,可以使用 vm.$emit('myEvent', payload)
來發送事件,該事件可以被父元件監聽。使用者在單擊 Follow
元件上的 Follow
按鈕時發出 followed
事件,我們將在父元件 UserList
中監聽它。
正如你所看到的,當 Follow
元件的 toggle()
觸發時,會通過 vm.$emit('followed', payload)
向父元件 UserList
傳送 followed
事件,這個時候 UserList
元件的方法 handleFollow(payload)
就會被被觸發。
通過上面的兩個示例向大家展示了兩種不同的方式進行元件之間的資料通訊。有關於Vue元件之間的資料通訊更多的教程,可以閱讀下面的文章。
使用Slot定製模板
Vue中的 props
對於傳遞變數和表示式很好,但是如果你想給HTML傳遞就行不通了。在Vue中可以使用 slot
來定製模板,這使得元件非常靈活。接來下看看如何通過 slot
給 Card
元件傳遞HTML所需要的內容。
在元件中新增 slot
可能是最簡單的,你只需要編輯 <template>
並新增 <slot></slot>
,也可以通過 name
給 slot
命名,比如 <slot name="title"></slot>
。呼叫 slot
也非常的簡單,只需要傳遞你的內容到 slot
中,像下面這樣:
<Card> <!-- default slot --> I will be shown in default slot <div slot="title"> As you guessed I will end up in title slot </div> </Card>
有關於Vue元件中關於 slot
更深入的介紹,可以閱讀《 Vue元件內容分發( slot
) 》一文。
Vue元件的生命週期的鉤子函式
下面是在Vue元件、例項的生命週期中觸發的鉤子。所有生命週期鉤子都將 this
上下文自動繫結到例項,以便你可以訪問 data
、 computed
和 methods
。
Vue提供的可以註冊的鉤子都在上圖中紅色框標註。他們是:
-
beforeCreate
:在例項初始化之後,資料觀測(Data Observer)和event
/watcher
事件配置之前被呼叫 -
created
:例項已經建立完成之後被呼叫。在這一步,例項已完成以下的配置:資料(Data Observer)、屬性和方法的運算,watch
/event
事件回撥。然而,掛載階段還沒開始,$el
屬性目前不可見 -
beforeMount
:在掛載開始之前被呼叫:相關的render
函式首次被呼叫 -
mounted
:el
被新建立的vm.$el
替換,並掛載到例項上去之後呼叫該鉤子。如果root
例項掛載了一個文件內元素,當mounted
被呼叫時vm.$el
也在文件內 -
beforeUpdate
:資料更新時呼叫,發生在虛擬DOM重新渲染和打補丁之前。你可以在這個鉤子中進一步地更改狀態,這不會觸發附加的重渲染過程 -
updated
:由於資料更改導致虛擬DOM重新渲染和打補丁,在這之後會呼叫該鉤子。當這個鉤子被呼叫時,元件DOM已經更新,所以你現在可以執行依賴於DOM的操作。然而在大多數情況下,你應該避免在此期間更改狀態,因為這可能會導致更新無限迴圈。該鉤子在伺服器端渲染期間不被呼叫 -
beforeDestroy
:例項銷燬之前呼叫。在這一步,例項仍然完全可用 -
destroyed
:Vue例項銷燬後呼叫。呼叫後,Vue例項指示的所有東西都會解繫結,所有的事件監聽器會被移除,所有的子例項也會被銷燬。該鉤子在伺服器端渲染期間不被呼叫
開啟瀏覽器的 console
檢視對應的生命週期鉤子函式相應的輸出結果:
有關於Vue生命週期更深入的介紹,可以閱讀《Vue例項和生命週期》一文。
Vue的Mixins
mixins
是Vue元件分發可重用功能的一種靈活方法。 mixins
物件可以包含元件的任何選項。當元件使用 mixins
時, mixins
中的所有選項將混入元件自己的選項。
你可能已經看到Bootstrap的很多元件有多種狀態,比如 success
、 error
、 warning
和 info
等。如果你想給一個按鈕新增 loading
、 warning
和 error
狀態,就可以通過建立一個 mixins
。除了在按鈕上可以使用之外,還可以在 Alert
、 Card
之類的元件使用這些狀態。
在上面的示例中,建立了 stateableMixin
和 closeableMixin
兩個 mixins
。 stateableMixin
給元素傳遞 type
型別,所以可以使用不同的狀態。 closeableMixin
新增關閉和切換行為。在Vue中可以同時使用多個 mixins
。比如上例中的 Card
和 Alert
元件中同時使用了這兩個 mixins
。
這就是它的要點,使用 mixins
,你可以建立一個一致的API,運用在整個運用程式中和你的元件一起工作。而且你可以始終在一個地方維護你的 mixins
,這樣做也會讓所有使用它的元件受益。
有關於Vue元件的 mixins
更多的介紹,可以閱讀《Vue中的Mixins》一文。
總結
這篇文章主要介紹了Vue的元件和 mixins
。可以涵蓋了Vue元件的很多方面,比如說:建立元件,元件資料通訊, EventBus
(事件匯流排)和生命週期以及 mixins
等。涉及的內容比較多,也比較零亂,不過還是希望你能在這篇文章中獲得自己想要的一些東西。如果文章中有不對之處,還請在下面的評論中指正,如果你有更多的經驗或建議,也歡迎在下面的評論中與我們一起分享。