
1 用法
假設(shè)父組件的模板包含子組件,我們可以通過(guò) props 來(lái)正向地把數(shù)據(jù)從父組件傳遞給子組件。props 可以是字符串?dāng)?shù)組,也可以是對(duì)象。
html:
<div id="app">
<deniro-component message=""嫦娥四號(hào)"成功發(fā)射升空 飛向月球背面要登陸"></deniro-component>
</div>
js:
Vue.component('deniro-component', {
props: ['message'],
template:
'<div>{{message}}</div>'
});
var app = new Vue({
el: '#app',
data: {}
});
渲染結(jié)果:
<div id="app"><div>"嫦娥四號(hào)"成功發(fā)射升空 飛向月球背面要登陸</div></div>
組件中的 props 與 data 函數(shù)的區(qū)別是:props 中的數(shù)組來(lái)自于父級(jí),而 data 函數(shù)是組件內(nèi)定義的數(shù)據(jù),所以它的作用域是組件本身。它們都可以在 template、computed 以及 methods 中使用。
如果需要傳遞多個(gè)數(shù)據(jù),直接在 props 數(shù)組中定義即可。
因?yàn)?HTML 不區(qū)分大小寫,所以當(dāng)使用 DOM 模板時(shí),建議直接使用短橫分隔(kebab-case)的命名方式來(lái)定義 props 參數(shù)名稱。
html:
<div id="app2">
<deniro-component2 special-message="微軟向谷歌投降重構(gòu)Edge 但I(xiàn)E瀏覽器為何將長(zhǎng)存"></deniro-component2>
</div>
js:
Vue.component('deniro-component2', {
props: ['specialMessage'],
template:
'<div>{{specialMessage}}</div>'
});
var app2 = new Vue({
el: '#app2',
data: {}
});
注意:如果使用的是字符串模板,那么可以忽略這個(gè)限制。
有時(shí)候,傳遞過(guò)來(lái)的數(shù)據(jù)來(lái)自于父級(jí)的動(dòng)態(tài)數(shù)據(jù),這是我們可以使用 v-bind 來(lái)動(dòng)態(tài)綁定 props 中的數(shù)據(jù)。
html:
<div id="app3">
<input type="text" v-model="parentMessage">
<deniro-component3 :message="parentMessage"></deniro-component3>
</div>
js:
Vue.component('deniro-component3', {
props: ['message'],
template:
'<div>{{message}}</div>'
});
var app3 = new Vue({
el: '#app3',
data: {
parentMessage:''
}
});
效果:

這里我們使用 v-model 綁定了父級(jí)數(shù)據(jù) parentMessage。所以當(dāng)在輸入框中鍵入的內(nèi)容,也會(huì)同步傳遞給子組件。
注意:如果不使用 v-bind 來(lái)傳遞數(shù)字、布爾對(duì)象、數(shù)組或者對(duì)象,那么傳遞的僅僅是字符串!
html:
<div id="app4">
<deniro-component4 :message="['a','b','c']"></deniro-component4>
<deniro-component4 message="['a','b','c']"></deniro-component4>
</div>
js:
Vue.component('deniro-component4', {
props: ['message'],
template:
'<div>參數(shù)類型:{{typeof message}};參數(shù)長(zhǎng)度:{{message.length}}</div>'
});
var app4 = new Vue({
el: '#app4',
data: {}
});
輸出結(jié)果:
參數(shù)類型:object;參數(shù)長(zhǎng)度:3
參數(shù)類型:string;參數(shù)長(zhǎng)度:13
2 改變單向數(shù)據(jù)流
Vue2.x 中,通過(guò) props 傳遞的數(shù)據(jù)是單向的,也就是說(shuō),如果父組件中的數(shù)據(jù)發(fā)生變化,那么也會(huì)影響到子組件中的數(shù)據(jù)。
有時(shí)候,因?yàn)闃I(yè)務(wù)場(chǎng)景的要求,我們需要改變這種單向數(shù)據(jù)流的設(shè)計(jì)。
2.1 作為初始值
子組件把父組件傳遞過(guò)來(lái)的值作為初始值,然后在自己的作用域內(nèi)隨意修改與使用它。這可以通過(guò)在子組件的 data 內(nèi)定義一個(gè)新數(shù)據(jù),用于引用父組件中的參數(shù)。
html:
<div id="app5">
<deniro-component5 :init-value="0"></deniro-component5>
</div>
js:
Vue.component('deniro-component5', {
props: ['initValue'],
template:
'<div>初始值:{{initValue}};<button @click="counter++">{{counter}}</button></div>',
data:function () {
return {
counter:this.initValue
}
}
});
var app5 = new Vue({
el: '#app5',
data: {}
});
效果:

組件中定義了 counter,它被初始化為傳入的 initValue,初始化之后,counter 就與 initValue 無(wú)關(guān)啦O(∩_∩)O~
2.2 轉(zhuǎn)換后傳入
有時(shí)候,我們必須把 props 中的值轉(zhuǎn)換后傳入子組件,這可以通過(guò)計(jì)算屬性來(lái)實(shí)現(xiàn)。
html:
<div id="app6">
<deniro-component6 :border="5" :width="200"></deniro-component6>
</div>
js:
Vue.component('deniro-component6', {
props: ['border', 'width'],
template:
'<div :style="style">一個(gè)算法通吃三大棋類</div>',
computed: {
style: function () {
return {
border: this.border + 'px solid red',
width: this.width + 'px'
}
}
}
});
var app6 = new Vue({
el: '#app6',
data: {}
});
效果:

注意:在 JS 中,對(duì)象與數(shù)組是引用類型,即子組件中定義的變量如果賦值的是這些類型,那么改變這些變量的值,是會(huì)影響到父組件的!
3 驗(yàn)證
我們自定義的組件,如果需要提供給第三方使用,那么最好進(jìn)行參數(shù)驗(yàn)證,這就需要用到對(duì)象寫法。如果驗(yàn)證失敗,那么會(huì)在瀏覽器的控制臺(tái)輸出警告日志。
html:
<div id="app7">
<deniro-component7 :a="'str'"></deniro-component7>
</div>
js:
<script src="https://cdn.bootcss.com/vue/2.2.2/vue.js"></script>
<script>
Vue.component('deniro-component7',{
props:{
a:Number
},
template:
'<div >{{a}}</div>',
});
var app7 = new Vue({
el: '#app7',
data: {}
});
</script>
注意:這里引入了開發(fā)版的 vue.js(生產(chǎn)版一般是 vue.min.js)。
控制臺(tái)輸出:

其它示例:
Vue.component('deniro-component8', {
props: {
//必須是數(shù)字類型
a: Number,
//數(shù)字類型或者字符串類型
b: [Number, String],
//布爾類型,默認(rèn)值為 true
c: {
type: Boolean,
default: true
},
//字符串類型,必須傳值
d: {
type: String,
required: true
},
//自定義
e: {
validator: function (v) {
return v > 1;
}
}
}
});
type 可以為這些類型:String、Number、Boolean、Object、Array、Function。
以上示例 DEMO