組件:
組件(Component)是 Vue.js 最強大的功能之一。組件可以擴展 HTML 元素,封裝可重用的代碼。在較高層面上,組件是自定義元素,Vue.js 的編譯器為它添加特殊功能。
使用:
使用Vue.extend()創建一個構造器
var userdefined = Vue.extend({ ... })
創建好元素之后,開始注冊元素,讓你定義的元素可以使用。
這里使用Vue.component去注冊組件
// 全局注冊組件,tag 為 my-component
Vue.component('u', userdefined) |
官方這里有一個注意:
對於自定義標簽名字,Vue.js 不強制要求遵循 W3C 規則(小寫,並且包含一個短杠),盡管遵循這個規則比較好。
注冊之后,就可以在HTML元素中使用了
<div id="app"> <u></u> </div> |
這里寫了個一個小例子,實現組件內的數據綁定,方法實現,鏈接:
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只能直接包含liselect只能包含option和optgrouptable只能直接包含thead,tbody,tfoot,tr,caption,col,colgrouptr只能直接包含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傳遞數據,組件實例的作用域是孤立的。這意味着不能並且不應該在子組件的模板內直接引用父組件的數據。可以使用 props 把數據傳給子組件。“prop” 是組件數據的一個字段,期望從父組件傳下來。子組件需要顯式地用 props 選項聲明 props。
我覺得這樣可以在視圖層顯示的傳遞數據,假如你封裝了一個form組件,增強復用性,就可以動態的更改action method方法了。當然,這個是我目前看到prosps 突然想到的,也能解決目前的一個小問題。
寫了兩個demo,鏈接:
https://jsfiddle.net/xeu84559/1/
https://jsfiddle.net/x00grrts/2/
camelCase-vs-kebab-case
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驗證
組件可以為 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 可以是下面原生構造器:
- String
- Number
- Boolean
- Function
- Object
- Array
type 也可以是一個自定義構造器,使用 instanceof 檢測。
當 prop 驗證失敗了,Vue 將拒絕在子組件上設置此值,如果使用的是開發版本會拋出一條警告。
加一個 props 動態綁定:
