Vue組件基礎用法
前面的話
組件(Component)是Vue.js最強大的功能之一。組件可以擴展HTML元素,封裝可重用的代碼。根據項目需求,抽象出一些組件,每個組件裏包含了展現、功能和樣式。每個頁面,根據自己所需,使用不同的組件來拼接頁面。這種開發模式使前端頁面易於擴展,且靈活性高,而且組件之間也實現了解耦。本文將詳細介紹Vue組件基礎用法
概述
組件是一個自定義元素或稱為一個模塊,包括所需的模板、邏輯和樣式。在HTML模板中,組件以一個自定義標簽的形式存在,起到占位符的功能。通過Vue.js的聲明式渲染後,占位符將會被替換為實際的內容
下面是一個最簡單的模塊示例
<div id="app"> <xiaohuochai></xiaohuochai> </div>
註冊組件
組件註冊包括全局註冊和局部註冊兩種
【全局註冊】
要註冊一個全局組件,可以使用 Vue.component(tagName, options)
Vue.component(‘my-component‘, { // 選項 })
組件在註冊之後,便可以在父實例的模塊中以自定義元素 <my-component></my-component>
的形式使用
[註意]要確保在初始化根實例之前註冊了組件
<div id="example"> <my-component></my-component> </div>
<script> // 註冊 Vue.component(‘my-component‘, { template: ‘<div>A custom component!</div>‘ }) // 創建根實例 new Vue({ el: ‘#example‘ }) </script>
【局部註冊】
通過使用組件實例選項components註冊,可以使組件僅在另一個實例/組件的作用域中可用
<div id="example"> <my-component></my-component> </div>
<script> // 註冊 var Child = { template: ‘<div>A custom component!</div>‘ }; // 創建根實例 new Vue({ el: ‘#example‘, components: { // <my-component> 將只在父模板可用 ‘my-component‘: Child } }) </script>
組件樹
使用組件實例選項components註冊,可以實現組件樹的效果
<div id="example"> <my-component></my-component> </div>
<script> // 註冊 var headerTitle = { template: ‘<p>我是標題</p>‘, }; var headerContent = { template: ‘<p>我是內容</p>‘, }; var header = { template: ` <div class="hd"> <header-content></header-content> <header-title></header-title> </div> `, components: { ‘header-content‘: headerContent, ‘header-title‘: headerTitle } }; // 創建實例 new Vue({ el: ‘#example‘, components: { ‘my-component‘: header } }) </script>
嵌套限制
並不是所有的元素都可以嵌套模板,因為要受到HTML元素嵌套規則的限制,尤其像<ul>
,<ol>
,<table>
,<select>
限制了能被它包裹的元素,而一些像 <option>
這樣的元素只能出現在某些其它元素內部
[註意]關於HTML標簽的詳細嵌套規則移步至此
在自定義組件中使用這些受限制的元素時會導致一些問題,例如
<table id="example"> <my-row>...</my-row> </table>
自定義組件 <my-row>
被認為是無效的內容,因此在渲染的時候會導致錯誤
<script> // 註冊 var header = { template: ‘<div class="hd">我是標題</div>‘ }; // 創建實例 new Vue({ el: ‘#example‘, components: { ‘my-row‘: header } }) </script>
【is屬性】
變通的方案是使用特殊的 is
屬性
<table id="example"> <tr is="my-row"></tr> </table>
<script> // 註冊 var header = { template: ‘<div class="hd">我是標題</div>‘ }; // 創建實例 new Vue({ el: ‘#example‘, components: { ‘my-row‘: header } }) </script>
data數據
一般地,我們在Vue實例對象或Vue組件對象中,我們通過data來傳遞數據
<div id="example"> <my-component></my-component> <my-component></my-component> <my-component></my-component> </div>
<script> // 註冊 Vue.component(‘my-component‘, { template: ‘<div>{{message}}</div>‘, data:{ message: ‘hello‘ } }) // 創建根實例 new Vue({ el: ‘#example‘ }) </script>
運行上面的代碼,會使Vue停止執行,並在控制臺發出錯誤提示,告訴你在組件中 data
必須是一個函數
可以用如下方式來繞開Vue的錯誤提示
<script> // 註冊 var data = {counter: 0} Vue.component(‘my-component‘, { template: ‘<button v-on:click="counter += 1">{{ counter }}</button>‘, data:function(){ return data; } }) // 創建根實例 new Vue({ el: ‘#example‘ }) </script>
由於這三個組件共享了同一個 data
,因此增加一個 counter 會影響所有組件!這不對。我們可以通過為每個組件返回全新的 data 對象來解決這個問題:
<script> // 註冊 Vue.component(‘my-component‘, { template: ‘<button v-on:click="counter += 1">{{ counter }}</button>‘, data:function(){ return {counter: 0}; } }) // 創建根實例 new Vue({ el: ‘#example‘ }) </script>
現在每個 counter 都有它自己內部的狀態了
父子級組件
【錯誤寫法】
現在來介紹兩種父子級組件的錯誤寫法
下面這種形式的寫法是錯誤的,因為當子組件註冊到父組件時,Vue.js會編譯好父組件的模板,模板的內容已經決定了父組件將要渲染的HTML <parent>...</parent>
運行時,它的一些子標簽只會被當作普通的HTML來執行,<child></child>不是標準的HTML標簽,會被瀏覽器直接忽視掉
<div id="example"> <parent> <child></child> <child></child> </parent> </div>
在父組件標簽之外使用子組件也是錯誤的
<div id="example"> <parent></parent> <child></child> </div>
【正確寫法】
<div id="example"> <parent></parent> </div>
<script> var childNode = { template: ‘<div>childNode</div>‘, } var parentNode = { template: ` <div class="parent"> <child></child> <child></child> </div> `, components: { ‘child‘: childNode } }; // 創建根實例 new Vue({ el: ‘#example‘, components: { ‘parent‘: parentNode } }) </script>
了解父子級組件的寫法後,下一篇博文將父子級組件間通信
歡迎交流
Vue組件基礎用法