組件 (Component) 是 Vue.js 最強大的功能之一。組件能夠擴展 HTML 元素,封裝可重用的代碼。html
咱們可使用 Vue.component(tagName, options)
註冊一個全局組件。vue
<!--全局註冊--> <template> <div id="app"> <my-component></my-component> </div> </template> <script> // 全局註冊組件 Vue.component('my-component', { template: '<div>個人組件</div>' }) // 建立根實例 new Vue({ el: '#app' }) </script> <!--渲染後的HTML--> <div id="app"> <div>個人組件</div> </div>
咱們還能夠經過某個 Vue
實例/組件的實例選項 components
註冊僅在其做用域中可用的組件,即局部組件。web
<!--局部註冊--> <template> <div id="app"> <my-component></my-component> </div> </template> <script> var Child = { template: '<div>個人組件</div>' } new Vue({ el: '#app', components: { // 局部註冊組件,<my-component> 將只在父組件模板中可用 'my-component': Child } }) </script> <!--渲染後的HTML--> <div id="app"> <div>個人組件</div> </div> 使用prop 組件實例的做用域是孤立的。父組件的數據須要經過 prop 才能下發到子組件中。 <!--靜態prop--> <template> <child message="哈嘍"></child> </template> <script> Vue.component('child', { // 聲明 props props: ['message'], // 就像 data 同樣,prop 也能夠在模板中使用 // 一樣也能夠在 vm 實例中經過 this.message 來使用 template: '<span>{{ message }}</span>' }) </script>
若是想要傳遞一個變量到子組件中去,即傳給子組件的值會跟隨父組件中該變量的值的變化而變化,咱們能夠用 v-bind
來動態地將 prop
綁定到父組件的數據。數組
<!--動態prop--> <template> <div id="dynamic-prop"> <input v-model="parentMsg"> <br> <child v-bind:my-message="parentMsg"></child> </div> </template> <script> new Vue({ el: '#dynamic-prop', data: { parentMsg: '父組件發過來的消息' } }) </script>
咱們還能夠爲組件的 prop
指定驗證規則。若是傳入的數據不符合要求,Vue
會發出警告。這對於開發給他人使用的組件很是有用。app
<!--prop驗證--> <script> Vue.component('example', { props: { // 基礎類型檢測 (`null` 指容許任何類型) propA: Number, // 多是多種類型 propB: [String, Number], // 必傳且是字符串 propC: { type: String, required: true }, // 數值且有默認值 propD: { type: Number, default: 100 }, // 數組/對象的默認值應當由一個工廠函數返回 propE: { type: Object, default: function () { return { message: 'hello' } } }, // 自定義驗證函數 propF: { validator: function (value) { return value > 10 } } } }) </script>
如今咱們父組件可使用 prop
傳遞數據給子組件。但子組件怎麼跟父組件進行通訊呢?這裏咱們能夠經過自定義事件來實現。框架
具體點說就是使用 $on(eventName)
監聽事件,使用 $emit(eventName, optionalPayload)
觸發事件。函數
<template> <div id="message-event"> <p v-for="msg in messages">{{ msg }}</p> <button-message v-on:message="handleMessage"></button-message> </div> </template> <script> Vue.component('button-message', { template: `<div> <input type="text" v-model="message" /> <button v-on:click="handleSendMessage">發送消息</button> </div>`, data: function () { return { message: '哈嘍' } }, methods: { handleSendMessage: function () { this.$emit('message', { message: this.message }) } } }) new Vue({ el: '#message-event', data: { messages: [] }, methods: { handleMessage: function (payload) { this.messages.push(payload.message) } } }) </script>
爲了讓組件能夠自由組合,咱們須要一種方式來混合父組件的內容與子組件本身的模板。這個過程被稱爲內容分發。咱們可使用特殊的 <slot>
元素做爲原始內容的插槽,從而實現內容分發。組件化
若是子組件模板包含一個 <slot>
插口,那麼父組件的內容將會被渲染到插槽中。ui
<!--子組件模板--> <templalte> <div> <h2>子組件的標題</h2> <slot> 只有在沒有要分發的內容時纔會顯示。 </slot> </div> </templalte> <!--父組件模板--> <template> <div> <h1>父組件的標題</h1> <my-component> <p>這是將會分發到子組件的一些初始內容</p> </my-component> </div> </template> <!--渲染後的HTML--> <div> <h1>父組件的標題</h1> <div> <h2>子組件的標題</h2> <p>這是將會分發到子組件的一些初始內容</p> </div> </div>
當須要有多個插槽時,咱們能夠在<slot>
元素上用一個特殊的特性 name
來進一步配置如何分發內容。多個插槽配置不一樣的名字,這時具名插槽將匹配內容片斷中有對應 slot
特性 name
的元素。this
<!--layout 子組件模板--> <template> <div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div> </template> <!--父組件模板--> <template> <layout> <h1 slot="header">頭部標題</h1> <p>主體內容的一個段落。</p> <p slot="footer">尾部版權信息</p> </layout> </template> <!--渲染後的HTML--> <div class="container"> <header> <h1>頭部標題</h1> </header> <main> <p>主體內容的一個段落。</p> </main> <footer> <p>尾部版權信息</p> </footer> </div>
本節主要知識點是vue.js
中組件的建立和註冊,父組件使用prop
向子組件傳遞數據並進行數據驗證,使用自定義事件進行組件間的通信,使用插槽來使組件能夠自由組合。vue.js
組件是vue
框架中最強大的功能,學完後相信你對web組件化也會有必定的瞭解了。