前言
在了解父子組件之前應(yīng)先掌握組件開發(fā)基礎(chǔ)。在實(shí)際開發(fā)過程中,組件之間可以嵌套,也因此生成父子組件。
父子組件創(chuàng)建流程
1.構(gòu)建父子組件
1.1 全局注冊(cè)
(1)構(gòu)建注冊(cè)子組件
//構(gòu)建子組件child
var child = Vue.extend({
template: '<div>這是子組件</div>'
});
//注冊(cè)名為'child'的組件
Vue.component('child',child);
(2)構(gòu)建注冊(cè)父組件
//構(gòu)建父組件parent,在其中嵌套child組件
var parent = Vue.extend({
template: '<div>這是父組件<child></child></div>'
});
Vue.component('parent',parent);
(3)定義vue實(shí)例
var app = new Vue({
el: '#app'
})
(4)使用父組件
<div id="app">
<parent></parent>
</div>
打開瀏覽器查看

1.2 局部注冊(cè)
(1)構(gòu)建子組件
var child = Vue.extend({
template: '<div>這是子組件</div>'
});
(2)構(gòu)建父組件
在父組件中局部注冊(cè)子組件
var parent = Vue.extend({
template: '<div>這是父組件<child></child></div>',
components:{
'child':child
}
});
(3)定義vue實(shí)例
在vue實(shí)例中局部注冊(cè)父組件
var app = new Vue({
el: '#app',
components:{
'parent':parent
}
})
(4)使用父組件
<div id="app">
<parent></parent>
</div>
2.父子組件間通信
2.1 父?jìng)髯?/h3>
父組件傳消息到子組件使用<code>props</code>,并且這傳遞是單向的,只能由父組件傳到子組件。我們將上面例子中的父組件增加一個(gè)數(shù)據(jù)傳遞到子組件中渲染顯示。如果父組件需要傳多個(gè)數(shù)據(jù)給子組件,依次在后面加即可。
(1)在父組件中增加data,并綁定到子組件上
var parent = Vue.extend({
template: '<div>這是父組件<child :pdata=data></child></div>',
data(){
return{
data:'這是父組件傳來的數(shù)據(jù)'
}
},
components:{
'child':child
}
});
其中<code><child :pdata=data></child></code>,<code>:pdata</code>是<code>v-bind:pdata</code>的縮寫,<code>pdata</code>是自定義傳遞數(shù)據(jù)的命名,子組件中也是用該名字獲取數(shù)據(jù),<code>data</code>是父組件中數(shù)據(jù)的命名。
(2)在子組件中通過props獲取數(shù)據(jù),并渲染出來
var child = Vue.extend({
template: '<div>這是子組件 {{pdata}}</div>',
props:['pdata']
});
查看瀏覽器

父組件中數(shù)據(jù)發(fā)生變化,子組件中自動(dòng)更新
子組件不可直接修改通過<code>props</code>獲取到的父組件中的數(shù)據(jù)
下面我們通過一個(gè)例子更好的理解上面兩句話
(1)使用<code><template></code>標(biāo)簽創(chuàng)建子組件
為方便書寫,我們使用<code><template></code>標(biāo)簽創(chuàng)建組件
<template id="child">
<div>
<p>這是子組件</p>
<table>
<tr>
<td>name</td>
<td>{{name}}</td>
<td><input type="text" v-model="name"></td>
</tr>
<tr>
<td>age</td>
<td>{{age}}</td>
<td><input type="text" v-model="age"></td>
</tr>
</table>
</div>
</template>
這里使用<code>v-model</code>指令來雙向綁定從父組件中獲取到的數(shù)據(jù)
(2)使用<code><template></code>標(biāo)簽創(chuàng)建父組件
<template id="parent">
<div>
<p>這是父組件</p>
<table>
<tr>
<td>name</td>
<td>{{name}}</td>
<td><input type="text" v-model="name"></td>
</tr>
<tr>
<td>age</td>
<td>{{age}}</td>
<td><input type="text" v-model="age"></td>
</tr>
</table>
//給子組件傳遞2個(gè)數(shù)據(jù)
<child :name="name" :age="age"></child>
</div>
</template>
(3)構(gòu)建子組件
var child = Vue.extend({
template: '#child',
props:['name','age']
});
(4)構(gòu)建父組件
var parent = Vue.extend({
template: '#parent',
data(){
return{
age:16,
name:'喬巴'
}
},
components:{
'child':child
}
});
查看瀏覽器

接著,我們?cè)诟附M件中修改輸入框的值,這會(huì)引起<code>v-model</code>綁定的值變化,同時(shí)也會(huì)改變子組件中的值

然后我們?cè)囍薷淖咏M件中輸入框的值,vue會(huì)警告不能直接修改父組件傳過來的值。

如果我們需要修改從父組件中props傳過來的值,最好一開始把這個(gè)值賦給另外一個(gè)data。
var child = Vue.extend({
template: '#child',
props:['name','age'],
data(){
return{
name1: '',
age1: ''
}
},
//頁面掛載時(shí)將props的值賦給子組件中的data
mounted:function(){
this.name1 = this.name
this.age1 = this.age
},
//同時(shí)增加監(jiān)聽,當(dāng)props的值發(fā)生變化時(shí),也立即賦值給子組件的data
watch:{
name:function(val){
this.name1 = this.name
},
age:function(val){
this.age1 = this.name
}
}
});
同時(shí)修改<code>v-model</code>綁定的<code>name</code>值為<code>name1</code>,<code>age</code>為<code>age1</code>
現(xiàn)在修改子組件中的值,就不會(huì)報(bào)錯(cuò)了,這是因?yàn)樽咏M件中修改的是<code>name1</code>,并不是props傳遞過來的<code>name</code>值

2.1 子傳父
子組件給父組件傳值通過<code>emit</code>。父組件需在子組件標(biāo)簽上綁定<code>emit</code>事件。
例子:
(1)構(gòu)建子組件
var child = Vue.extend({
template: '<div><button @click="change">點(diǎn)擊給父組件傳值</button></div>',
methods:{
change: function(){
this.$emit('posttoparent',10)
}
}
});
子組件按鈕綁定了一個(gè)<code>click</code>事件,當(dāng)點(diǎn)擊按鈕執(zhí)行<code>change</code>方法,該方法觸發(fā)<code>emit</code>事件,事件名為<code>posttoparent</code>,并且?guī)Я艘粋€(gè)參數(shù)10。
(2)構(gòu)建父組件
var parent = Vue.extend({
template: '<div>來自子組件的值為:{{datafromchild}} <child v-on:posttoparent="getfromchild"></child></div>',
data(){
return{
datafromchild:''
}
},
components:{
'child':child
},
methods: {
getfromchild: function(val){
this.datafromchild = val
}
}
});
父組件接收emit事件通過v-on指令,格式為:
v-on:emit方法名="父組件方法"
父組件將接收到的參數(shù)賦值給<code>datafromchild </code>
查看瀏覽器

3.兄弟組件間通信
兄弟組件間通信也是用的<code>emit</code>。但原生vue.js需要新建一個(gè)空的vue實(shí)例來當(dāng)橋梁。
下面直接貼代碼
//新建一個(gè)空的vue實(shí)例bus
var bus = new Vue();
var myCom1 = Vue.extend({
template: '<div><button @click="change">點(diǎn)擊給兄弟組件傳值</button></div>',
methods:{
change: function(){
//通過空實(shí)例去觸發(fā)emit
bus.$emit('posttobro',10)
}
}
});
var myCom2 = Vue.extend({
template: '<div>來自兄弟組件的值為:{{datafrombro}}</div>',
data(){
return{
datafrombro:''
}
},
mounted:function(){
//接收emit事件
bus.$on('posttobro',function(val){
this.datafrombro = val
}.bind(this))
}
});
Vue.component('my-com1',myCom1);
Vue.component('my-com2',myCom2);
var app = new Vue({
el: '#app'
});
使用組件
<div id="app">
<my-com1></my-com1>
<my-com2></my-com2>
</div>
查看瀏覽器
