前言
在瞭解父子組件之前應先掌握組件開發基礎。在實際開發過程中,組件之間可以嵌套,也因此生成父子組件。
父子組件創建流程
1.構建父子組件
1.1 全局註冊
(1)構建註冊子組件
//構建子組件child
var child = Vue.extend({
template: '<div>這是子組件</div>'
});
//註冊名爲'child'的組件
Vue.component('child',child);
(2)構建註冊父組件
//構建父組件parent,在其中嵌套child組件
var parent = Vue.extend({
template: '<div>這是父組件<child></child></div>'
});
Vue.component('parent',parent);
(3)定義vue實例
var app = new Vue({
el: '#app'
})
(4)使用父組件
<div id="app">
<parent></parent>
</div>
打開瀏覽器查看
1.2 局部註冊
(1)構建子組件
var child = Vue.extend({
template: '<div>這是子組件</div>'
});
(2)構建父組件
在父組件中局部註冊子組件
var parent = Vue.extend({
template: '<div>這是父組件<child></child></div>',
components:{
'child':child
}
});
(3)定義vue實例
在vue實例中局部註冊父組件
var app = new Vue({
el: '#app',
components:{
'parent':parent
}
})
(4)使用父組件
<div id="app">
<parent></parent>
</div>
2.父子組件間通信
2.1 父傳子
父組件傳消息到子組件使用<code>props</code>,並且這傳遞是單向的,只能由父組件傳到子組件。我們將上面例子中的父組件增加一個數據傳遞到子組件中渲染顯示。如果父組件需要傳多個數據給子組件,依次在後面加即可。
(1)在父組件中增加data,並綁定到子組件上
var parent = Vue.extend({
template: '<div>這是父組件<child :pdata=data></child></div>',
data(){
return{
data:'這是父組件傳來的數據'
}
},
components:{
'child':child
}
});
其中<code><child :pdata=data></child></code>,<code>:pdata</code>是<code>v-bind:pdata</code>的縮寫,<code>pdata</code>是自定義傳遞數據的命名,子組件中也是用該名字獲取數據,<code>data</code>是父組件中數據的命名。
(2)在子組件中通過props獲取數據,並渲染出來
var child = Vue.extend({
template: '<div>這是子組件 {{pdata}}</div>',
props:['pdata']
});
查看瀏覽器
父組件中數據發生變化,子組件中自動更新
子組件不可直接修改通過<code>props</code>獲取到的父組件中的數據
下面我們通過一個例子更好的理解上面兩句話
(1)使用<code><template></code>標籤創建子組件
爲方便書寫,我們使用<code><template></code>標籤創建組件
<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>指令來雙向綁定從父組件中獲取到的數據
(2)使用<code><template></code>標籤創建父組件
<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個數據
<child :name="name" :age="age"></child>
</div>
</template>
(3)構建子組件
var child = Vue.extend({
template: '#child',
props:['name','age']
});
(4)構建父組件
var parent = Vue.extend({
template: '#parent',
data(){
return{
age:16,
name:'喬巴'
}
},
components:{
'child':child
}
});
查看瀏覽器
接着,我們在父組件中修改輸入框的值,這會引起<code>v-model</code>綁定的值變化,同時也會改變子組件中的值
然後我們試着修改子組件中輸入框的值,vue會警告不能直接修改父組件傳過來的值。
如果我們需要修改從父組件中props傳過來的值,最好一開始把這個值賦給另外一個data。
var child = Vue.extend({
template: '#child',
props:['name','age'],
data(){
return{
name1: '',
age1: ''
}
},
//頁面掛載時將props的值賦給子組件中的data
mounted:function(){
this.name1 = this.name
this.age1 = this.age
},
//同時增加監聽,當props的值發生變化時,也立即賦值給子組件的data
watch:{
name:function(val){
this.name1 = this.name
},
age:function(val){
this.age1 = this.name
}
}
});
同時修改<code>v-model</code>綁定的<code>name</code>值爲<code>name1</code>,<code>age</code>爲<code>age1</code>
現在修改子組件中的值,就不會報錯了,這是因爲子組件中修改的是<code>name1</code>,並不是props傳遞過來的<code>name</code>值
2.1 子傳父
子組件給父組件傳值通過<code>emit</code>。父組件需在子組件標籤上綁定<code>emit</code>事件。
例子:
(1)構建子組件
var child = Vue.extend({
template: '<div><button @click="change">點擊給父組件傳值</button></div>',
methods:{
change: function(){
this.$emit('posttoparent',10)
}
}
});
子組件按鈕綁定了一個<code>click</code>事件,當點擊按鈕執行<code>change</code>方法,該方法觸發<code>emit</code>事件,事件名爲<code>posttoparent</code>,並且帶了一個參數10。
(2)構建父組件
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方法名="父組件方法"
父組件將接收到的參數賦值給<code>datafromchild </code>
查看瀏覽器
3.兄弟組件間通信
兄弟組件間通信也是用的<code>emit</code>。但原生vue.js需要新建一個空的vue實例來當橋樑。
下面直接貼代碼
//新建一個空的vue實例bus
var bus = new Vue();
var myCom1 = Vue.extend({
template: '<div><button @click="change">點擊給兄弟組件傳值</button></div>',
methods:{
change: function(){
//通過空實例去觸發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>
查看瀏覽器