組件實例的做用域是相互獨立的,父、子組件之間沒法進行數據的共享。
若是想在子組件模板中使用父組件的數據,能夠經過Prop將父組件的數據下發到子組件。子組件用props
選項聲明它預期的數據。javascript
爲了傳遞數據,父組件必須先在子組件自定義標籤的特性上綁定數據,綁定的值分兩種狀況解析:html
prop="value"
v-bind:prop="expression"
v-bind="Object"
new Vue({ el: '#app-1', data: { parentMsg: 'root\'s dynamic data', parentObj: { text:'hello vue!', isShow: true }, }, components: { 'component-1': { props: ['expectMsg','expectDynamicMsg','expectObj','text','isShow'], template: '\ <div>\ <p>{{expectMsg}}</p>\ <p>{{expectDynamicMsg}}</p>\ <p v-show="expectObj.isShow">{{expectObj.text}}</p>\ <p v-show="isShow">{{text}}</p>\ </div>' }
<div id="app-1"> <!-- 字面量綁定、動態綁定、動態綁定一個對象、動態綁定特例 --> <component-1 expect-msg="static data" v-bind:expect-dynamic-msg="parentMsg" v-bind:expect-obj="parentObj" v-bind="parentObj"> </component-1> </div>
這裏分別做了幾種綁定的示例:vue
"static data"
綁定到子組件的props
的expectMsg
上parentMsg
動態綁定到子組件的expectDynamicMsg
特性上parentObj
動態綁定到子組件的expectObj
特性上parentObj
對象的屬性text、isShow
綁定到子組件的text
和isShow
特性上注意:要下發一個數字給子組件不能使用字面量綁定,字面量下發的都是字符串。所以須要動態綁定java
<component v-bind:some-number="1">
當要對下發數據作驗證或在無數據時設置默認值,子組件選項props
就須要使用一個對象替換數組。
簡單的狀況:express
props:{ someProp:String }
下發數據必須是一個字符串數組
複雜點能夠設置默認值與驗證器,如:app
new Vue({ el: '#app-2', data:{ message:{ title:'prop驗證', text:'父組件數據' } }, components: { 'component-2': { props: { propObj:{ type:Object, //下發對象的title屬性必須是個字符串 validator:function(value){ return typeof value.title === "string" }, //下發數據爲一個數組或對象,設置的默認值必須由一個函數返回 default:function(){ return {title:'prop驗證',text:'數組/對象的默認值應當由一個工廠函數返回'} } } }, template: '<div><h5>{{propObj.title}}</h5><p>{{propObj.text}}</p></div>' } } })
<div id="app-2"> <component-2 v-bind:prop-obj="message"></component-2> </div>
type屬性也能夠是一個函數,使用instanceof
驗證。驗證在子組件實例建立以前進行,所以驗證裏的任何函數都沒法使用子組件實例屬性。ide
更多類型驗證 Prop驗證函數
下發數據實際上就是完成一個數據綁定的過程,把組件間的特定數據綁定在一塊兒,默認狀況下爲單向綁定,子組件的數據對於父組件是透明的,而父組件的數據變化則會引起子組件數據的變化。ui
new Vue({ el: '#app-3', data: { content: "please input..." }, components: { 'component-3': { props:['txt'], template:'<div><input v-model="txt"></div>' } } })
<div id="app-3"> <input v-model="content"> <br/> <component-3 v-bind:txt="content"></component-3> </div>
父組件經過Prop
下發數據,將父組件屬性content
和子組件特性txt
綁定在一塊兒,在第一文本框輸入值改變content
的內容,子組件的txt
會跟隨變化,顯示在第二個文本框中。
若是在子模板第二個文本框輸入,修改txt
的值時,父組件控制的第一個文本框內容不會改變。
並在控制檯給出警告,說不要修改props
選項中的值,做爲代替,可讓prop
的值賦予data
或者computed
屬性使用。所以能夠像下面這樣用data
替代prop
做爲一個局部變量。
'component-3': { props:['txt'], template:'<div><input v-model="txtData"></div>', data:function(){ return {txtData:this.txt} } }
若只考慮輸出不考慮輸入,也可使用計算屬性替代
'component-3': { props: ['txt'], template: '<div><input v-model="txtComputed"></div>', computed: { txtComputed:function() { return this.txt } } }
組件的做者卻並不總能預見到組件被使用的場景。因此,組件能夠接收任意傳入的特性,這些特性都會被添加到組件的根元素上,而不須要定義響應的props
。
var vm = new Vue({ el: '#app-4', components: { "component-4": { template: "<button class='btn-sm'>hello vue!</button>" } } });
<div id="app-4"> <component-4 data-title="learn vue" class="btn-info"></component-4> </div>
渲染結果
<button class="btn-sm btn btn-info" data-title="learn vue">hello vue!</button>
其中data-title
、class
就是非Prop特性。
由於沒有在組件中定義props
,所以也沒法去引用它們,做用目前不明顯。
從渲染結果還能夠發現,class
特性的值由子組件模板和父模板定義的特性合併而成,對於class
和style
是這樣合併結果。但對於多數組件來講,傳遞給組件的值會覆蓋組件自己設定的值。