組件
組件可以大致的分爲三類
- 父組件
- 子組件
- 兄弟組件
當使用組件時,往往可能會遇到這樣的問題
如果我想通過父組件向子組件傳值,我應該怎麼辦?
同樣的道理,子組件向父組件傳值怎麼辦?
組件之間傳值也可以分爲三類
- 父組件向子組件傳值
- 子組件向父組件傳值
- 兩個兄弟之間的組件傳值
父組件向子組件傳值
父組件以屬性的形式將要傳遞的值綁定到子組件身上,然後子組件再通過props
屬性接收傳遞的值
<div id="app">
// 將要傳遞的值綁定在屬性上
<cpn :title="msg" :num1="num" num2="num" :arr1="arr" arr2="arr"></cpn>
</div>
<script>
Vue.component('cpn', {
// 利用 props 屬性接收傳遞的值
props: ['title', 'num1', "num2", 'arr1', 'arr2'],
data() {
return {
msg: '子組件'
}
},
template: `
<div>
<div>{{msg}}</div>
<div>{{title}}</div>
<div>{{typeof num1}}</div>
<div>{{typeof arr2}}</div>
<li v-for="item in arr1">{{item}}</li>
<li v-for="item in arr2">{{item}}</li>
</div
`
})
new Vue({
el: '#app',
data: {
msg: '父組件',
num: 1,
arr: ['張三', '李四', '王麻子'],
obj: {
name: '張三',
age: 18
}
}
})
注意
1.傳的值可以是數字、對象、數組等,傳的值動態綁定(v-bind:)和靜態綁定是有區別的,靜態綁定傳遞的值的類型最終都會變成字符串類型,另外如果對這個值進行遍歷的話,動態綁定的值(假如是數組),那麼將會將數組的每一項輸出,但如果是靜態綁定的話,將會把傳遞的值的名稱打印(arr),具體看上面的例子
2.在props中使用駝峯形式,模板的名字需要使用短橫線的形式,字符串形式的模板中沒有這個限制
3.單向綁定
子組件向父組件傳值
子組件向父組件傳值主要是通過事件監聽的方式來實現的
子組件使用$emait
來觸發事件,然後父組件通過v-on
來監聽子組件的事件
$emit
的第一個參數用來自定義事件的名稱,第二個參數用來傳遞要傳遞的值
<div id="app">
<div>子組件傳過來的內容是:{{msg}}</div>
<!-- 父組件監聽子組件的事件 -->
<cpn @post-data="handle($event)"></cpn>
</div>
<script>
Vue.component('cpn', {
data() {
return {
msg: '我是子組件傳過來的內容'
}
},
// 子組件使用 $emit 來觸發事件
template: `
<div>
<div>11111111</div>
<button @click='$emit("post-data", msg)'>按鈕</button>
</div>
`
})
var vm = new Vue({
el: '#app',
data: {
msg: ''
},
methods: {
handle(value) {
this.msg = value;
}
}
})
</script>
兄弟組件之間傳值
兄弟組件之間的傳值主要藉助於事件中心來傳值
主要步驟:
1.提供事件中心var hub = new Vue()
2.傳遞數據,通過觸發hub.$emit(方法名, 傳遞的值)
事件來傳遞值
3.接收數據,在mounted(){}
鉤子中,通過觸發```hub.$off()``方法來接收數據
4.另外,還可以通過hub.$off(name)
方法l來銷燬,銷燬之後就無法進行傳遞值了
<div id="app">
<div>父組件</div>
<div>
<button @click='handle'>銷燬事件</button>
</div>
<test-tom></test-tom>
<test-jerry></test-jerry>
</div>
<script>
//1、 提供事件中心
var hub = new Vue();
Vue.component('test-tom', {
data: function(){
return {
num: 0
}
},
template: `
<div>
<div>TOM:{{num}}</div>
<div>
<button @click='handle'>點擊</button>
</div>
</div>
`,
methods: {
handle: function(){
//2、傳遞數據方,通過一個事件觸發hub.$emit(方法名,傳遞的數據) 觸發兄弟組件的事件
hub.$emit('jerry-event', 2);
}
},
mounted: function() {
// 3、接收數據方,通過mounted(){} 鉤子中 觸發hub.$on(方法名
hub.$on('tom-event', (val) => {
this.num += val;
});
}
});
Vue.component('test-jerry', {
data: function(){
return {
num: 0
}
},
template: `
<div>
<div>JERRY:{{num}}</div>
<div>
<button @click='handle'>點擊</button>
</div>
</div>
`,
methods: {
handle: function(){
//2、傳遞數據方,通過一個事件觸發hub.$emit(方法名,傳遞的數據) 觸發兄弟組件的事件
hub.$emit('tom-event', 1);
}
},
mounted: function() {
// 3、接收數據方,通過mounted(){} 鉤子中 觸發hub.$on()方法名
hub.$on('jerry-event', (val) => {
this.num += val;
});
}
});
var vm = new Vue({
el: '#app',
data: {
},
methods: {
handle: function(){
//4、銷燬事件 通過hub.$off()方法名銷燬之後無法進行傳遞數據
hub.$off('tom-event');
hub.$off('jerry-event');
}
}
});
</script>