一、Vue中的組件
- 組件(Component)是Vue.js最強大的功能之一,組件可以擴展HTML元素,封裝可重用的代碼;
- 怎么聲明一個組件:
// js
Vue.component('my-component',{
template: '<h1>Hello Vue.js</h1>'
})
var app = new Vue({
el: '#app'
})
// HTML
<div id="app">
<my-component></my-component>
</div>
注意:HTML 特性不區分大小寫。當使用非字符串模版時,prop的名字形式會從 camelCase 轉為 kebab-case(短橫線隔開)。
二、父子組件通信
組件實例的作用域是孤立的;這意味著不能并且不應該在子組件的模板內直接引用父組件的數據。但是父子組件之間需要通信:父組件要給子組件傳遞數據,子組件需要將它內部發生的事情告知給父組件。
單向數據流這是父子組件的核心概念,prop是單向綁定的。當父組件的屬性發生變化的時候,會傳導到子組件。但是反之,為了防止子組件無意間修改來父組件的狀態,從下往上的數據流是不允許的。
如果子組件要把數據傳遞回去,應該怎樣做?那就是自定義事件!
- 使用 $on(eventName) 監聽事件
- 使用 $emit(eventName) 觸發事件
// js
Vue.component('child', {
template: `
<div>
<spam>我是child</spam>
<button>關閉</button>
</div>
`
})
new Vue({
el: '#parent',
data: {
visible: false
}
})
// HTML
<div id="parent">
<button @click="visible=true">打開</button>
<child v-show="visible"></child>
</div>
當點擊打開按鈕的時候,child將會顯示出來,那要將它關閉怎么辦呢?child是不能關閉自己的,因為它是否顯示是由他parent決定的。我們可以通知它parent:
// js
Vue.component('child', {
template: `
<div>
<spam>我是child</spam>
<button @click="$emit('close')">關閉</button>
</div>
`
})
new Vue({
el: '#parent',
data: {
visible: false
}
})
// HTML
<div id="parent">
<button @click="visible=true">打開</button>
<child v-show="visible" @close="visible=false"></child>
</div>
這樣在點擊關閉按鈕,會觸發close事件parent會讓‘visible = false’,這個時候v-show就會更新,這是響應式。
三、爺孫無法通信
在上述的列子中假設還有一個grandson
// js
Vue.component('child', {
template: `
<div>
<spam>我是child</spam>
<grandson></grandson>
</div>
`
})
Vue.component('grandson', {
template: `
<div>
<spam>我是grandson</spam>
<button @click="$emit('close')">關閉</button>
</div>
`
})
new Vue({
el: '#grandpa',
data: {
visible: false
}
})
// HTML
<div id="grandpa">
<child></child>
</div>
這個時候想讓grandpa(也就是上一個列子中的parent)直接關閉grandson,不可以的。要控制grandson的可見性只能讓child來
// js
Vue.component('child', {
props: ['showme'],
template: `
<div>
<spam>我是child</spam>
<grandson v-show="showme" @close="$emit('close')"></grandson>
</div>
`
})
Vue.component('grandson', {
template: `
<div>
<spam>我是grandson</spam>
<button @click="$emit('close')">關閉</button>
</div>
`
})
new Vue({
el: '#grandpa',
data: {
visible: false
}
})
// HTML
<div id="grandpa">
<button @click="visible=true">打開</button>
<child :showme="visible" @close="visible=false"></child>
</div>
就是說爺孫之間是無法通信的,只能一級一級的往上傳,grandson告訴child我要關閉了,child監聽close事件,然后再告訴grandpa,grandpa就會監聽child。
四、兄弟組件通信
根據官方文檔的教程,使用一個空的 Vue 實例作為事件總線
$on方法用來監聽一個事件。
$emit用來觸發一個事件。
//新建一個Vue實例作為中央事件總線
let bus= new Vue();
//監聽事件
bus.$on('eventName', (val) => {
//......do something
});
//觸發事件
bus.$emit('eventName', 'this is a message.');