組件(Component)是 Vue.js 最強大的功能之一。組件能夠擴展 HTML 元素,封裝可重用的代碼。在較高層面上,組件是自定義元素,Vue.js 的編譯器爲它添加特殊功能。html
使用:vue
使用Vue.extend()建立一個構造器api
var userdefined = Vue.extend({ ... })
數組
建立好元素以後,開始註冊元素,讓你定義的元素可使用。瀏覽器
這裏使用Vue.component去註冊組件app
// 全局註冊組件,tag 爲 my-component
Vue.component('u', userdefined) |
官方這裏有一個注意:函數
對於自定義標籤名字,Vue.js 不強制要求遵循 W3C 規則(小寫,而且包含一個短槓),儘管遵循這個規則比較好。ui
註冊以後,就能夠在HTML元素中使用了spa
<div id="app"> <u></u> </div> |
這裏寫了個一個小例子,實現組件內的數據綁定,方法實現,連接:.net
https://jsfiddle.net/miloer/x00grrts/
注意組件的模板替換了自定義元素,自定義元素的做用只是做爲一個掛載點。這能夠用實例選項 replace
改變。
局部註冊:
在自定義組件裏,添加另外一個自定義組件,只是在父元素組件裏進行調用。連接:
https://jsfiddle.net/miloer/x00grrts/1/
一開始我覺得這麼用:
html:
<div id="#app"> <other><u><u/></other> </div>
但這樣只解析other的,並且這樣還不符合Vue的設計風格,而後在想一想,明白了。
註冊語法糖
// 在一個步驟中擴展與註冊
Vue.component('my-component', { template: '<div>A custom component!</div>' }) // 局部註冊也能夠這麼作 var Parent = Vue.extend({ components: { 'my-component': { template: '<div>A custom component!</div>' } } })
爲了讓事件更簡單,能夠直接傳入選項對象而不是構造器給 Vue.component()
和component
選項。Vue.js 在背後自動調用 Vue.extend()
Vue 的模板是 DOM 模板,使用瀏覽器原生的解析器而不是本身實現一個。相對於字符串模板這有一些好處,可是也有問題。DOM 模板必須是有效的 HTML 片斷。一些 HTML 元素對什麼元素能夠放在它裏面有限制。常見的限制:
a
不能包含其它的交互元素(如按鈕,連接)ul
和 ol
只能直接包含 li
select
只能包含 option
和 optgroup
table
只能直接包含 thead
, tbody
, tfoot
, tr
, caption
, col
, colgroup
tr
只能直接包含 th
和 td
在實際中,這些限制會致使意外的結果。儘管在簡單的狀況下它可能能夠工做,可是你不能依賴自定義組件在瀏覽器驗證以前的展開結果。例如<my-select><option>...</option></my-select>
不是有效的模板,即便 my-select
組件最終展開爲 <select>...</select>
。
另外一個結果是,自定義標籤(包括自定義元素和特殊標籤,如<component>
、<template>
、 <partial>
)不能用在 ul
, select
, table
等對內部元素有限制的標籤內。放在這些元素內部的自定義標籤將被提到元素的外面,於是渲染不正確。
對於自定義元素,應當使用 is
特性:
<table> <tr is="my-component"></tr> </table> |
<template>
不能用在 <table>
內,這時應使用 <tbody>
,<table>
能夠有多個<tbody>
:
<table> <tbody v-for="item in items"> <tr>Even row</tr> <tr>Odd row</tr> </tbody> </table> |
組件裏的涉及的內容挺多的,不過越豐富功能就越完善。
使用props傳遞數據,組件實例的做用域是孤立的。這意味着不能而且不該該在子組件的模板內直接引用父組件的數據。可使用 props 把數據傳給子組件。「prop」 是組件數據的一個字段,指望從父組件傳下來。子組件須要顯式地用 props
選項聲明 props。
我以爲這樣能夠在視圖層顯示的傳遞數據,假如你封裝了一個form組件,加強複用性,就能夠動態的更改action method方法了。固然,這個是我目前看到prosps 忽然想到的,也能解決目前的一個小問題。
寫了兩個demo,連接:
https://jsfiddle.net/xeu84559/1/
https://jsfiddle.net/x00grrts/2/
HTML 特性不區分大小寫。名字形式爲 camelCase 的 prop 用做特性時,須要轉爲 kebab-case(短橫線隔開):
Vue.component('child', { // camelCase in JavaScript props: ['myMessage'], template: '<span>{{ myMessage }}</span>' })
<!-- kebab-case in HTML -->
<child my-message="hello!"></child>
組件能夠爲 props 指定驗證要求。當組件給其餘人使用時這頗有用,由於這些驗證要求構成了組件的 API,確保其餘人正確地使用組件。此時 props 的值是一個對象,包含驗證要求:
Vue.component('example', { props: { // 基礎類型檢測 (`null` 意思是任何類型均可以) propA: Number, // 多種類型 (1.0.21+) propM: [String, Number], // 必需且是字符串 propB: { type: String, required: true }, // 數字,有默認值 propC: { type: Number, default: 100 }, // 對象/數組的默認值應當由一個函數返回 propD: { type: Object, default: function () { return { msg: 'hello' } } }, // 指定這個 prop 爲雙向綁定 // 若是綁定類型不對將拋出一條警告 propE: { twoWay: true }, // 自定義驗證函數 propF: { validator: function (value) { return value > 10 } }, // 轉換函數(1.0.12 新增) // 在設置值以前轉換值 propG: { coerce: function (val) { return val + '' // 將值轉換爲字符串 } }, propH: { coerce: function (val) { return JSON.parse(val) // 將 JSON 字符串轉換爲對象 } } } })
type
能夠是下面原生構造器:
type
也能夠是一個自定義構造器,使用 instanceof
檢測。
當 prop 驗證失敗了,Vue 將拒絕在子組件上設置此值,若是使用的是開發版本會拋出一條警告。
加一個 props 動態綁定: