本部落格主要是介紹各種情景下的Vue元件間的通訊
一、父元件向子元件通訊
1、使用props
使用props,父元件可以使用props向子元件傳遞資料。
<div id="demo1">
<children-div-1 v-bind:parent-message="message"></children-div-1>
</div>
Vue.component("children-div-1",{
props:["parentMessage"],
template : `
<div>
<p>{{ parentMessage }}</p>
</div>
`
});
new Vue({
el : "#demo1",
data : {
message : "這裡是來自父元件的訊息"
}
});
複製程式碼
2、使用$children(不推薦)
$children返回元件的一個子元件集合
<div id="demo2">
<p @click="changeMessage">點選改變子元件的訊息</p>
<children-div-2></children-div-2>
</div>
var childrenDiv2 = {
template : `
<div>
<p>{{ message }}</p>
</div>
`,
data : function(){
return {message : "這裡是子元件訊息"}
}
}
new Vue({
el : "#demo2",
components : {
"children-div-2" : childrenDiv2
},
methods : {
changeMessage : function(){
this.$children[0].message = "父元件改變了子元件的訊息";
}
}
});
複製程式碼
二、子元件向父元件通訊
1、使用vue事件
父元件向子元件傳遞事件方法,子元件通過$emit觸發事件,回撥給父元件。
<div id="demo3">
<children-div-3 v-on:change-message="changeMessage"></children-div-3>
<p>{{ message }}</p>
</div>
Vue.component("children-div-3",{
template : `
<div>
<p @click="$emit('change-message','子元件要求改變訊息')">點選改變父元件的訊息</p>
</div>
`
});
new Vue({
el : "#demo3",
data : {
message : "這裡是父元件的訊息"
},
methods : {
changeMessage : function(data){
this.message = data;
}
}
});
複製程式碼
2、使用$parent(不推薦)
$parent返回元件的父元件
<div id="demo4">
<children-div-4></children-div-4>
<p>{{ message }}</p>
</div>
Vue.component("children-div-4",{
template : `
<div>
<p @click="changeMessage">點選改變父元件的訊息</p>
</div>
`,
methods : {
changeMessage : function(){
this.$parent.message = "子元件要求改變訊息";
}
}
});
new Vue({
el : "#demo4",
data : {
message : "這裡是父元件的訊息"
}
});
複製程式碼
三、多層級父子元件通訊
1、使用inheritAttrs + $attrs + $listenerst
inheritAttrs:預設值為true,設定為false時,沒有被子元件繼承的父元件屬性(子元件的屬性定義在元件的props中),不會當做特性展示在子元件根元素上面。
預設情況下父作用域的不被認作props的特性繫結(attribute bindings)將會“回退”且作為普通的HTML特性應用在子元件的根元素上。
當撰寫包裹一個目標元素或另一個元件的元件時,這可能不會總是符合預期行為。
通過設定 inheritAttrs 到 false,這些預設行為將會被去掉。
而通過 (同樣是 2.4 新增的) 例項屬性 $attrs 可以讓這些特性生效,且可以通過 v-bind 顯性的繫結到非根元素上。
複製程式碼
$attrs:存放沒有被子元件繼承的的資料物件
包含了父作用域中不被認為 (且不預期為) props 的特性繫結 (class 和 style 除外)。
當一個元件沒有宣告任何 props 時,這裡會包含所有父作用域的繫結 (class 和 style 除外),
並且可以通過 v-bind=”$attrs” 傳入內部元件——在建立更高層次的元件時非常有用。
複製程式碼
$listeners:含了作用在這個元件上的所有監聽器
包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監聽器。
它可以通過 v-on=”$listeners” 傳入內部元件——在建立更高層次的元件時非常有用.
複製程式碼
父元件中未被props(v-on)繫結的屬性(事件) 可以在子元件中,通過 $attrs, $listeners 獲取。
<div id="demo6">
<p>{{ message }}</p>
<!-- 向後代元件傳遞訊息並且繫結時間監聽 -->
<children-div-6
v-bind:son-message="sonMessage"
v-bind:grandson-message="grandsonMessage"
v-on:change="change"
></children-div-6>
</div>
var grandSonDiv = {
props : ["grandsonMessage"],
template : `
<div>
<p @click="$emit('change','這裡是來自後代元件的訊息')">{{ grandsonMessage }}</p>
</div>
`,
}
var childrenDiv ={
props : ["sonMessage"],
// inheritAttrs設定為false,子元件只獲取props中定義屬性所接送的訊息,其餘的都不繼承,儲存在$attrs中
// $attrs 獲取沒有被子元件繼承的資料物件,傳遞給後代元件
// v-on="$listeners" 包含了所有的監聽器,所以將後代元件觸發的事件通報給父元件
template : `
<div>
<p>{{ sonMessage }}</p>
<grandson-div v-bind=$attrs v-on="$listeners"></grandson-div>
</div>
`,
inheritAttrs : false,
components : {
"grandson-div" : grandSonDiv
}
};
new Vue({
el : "#demo6",
data : {
message : "這裡是父元件自己的訊息",
sonMessage : "這是給子元件的訊息",
grandsonMessage : "這是給後代元件的訊息"
},
components : {
"children-div-6" : childrenDiv
},
methods : {
change : function(val){
this.message = val;
}
}
})
複製程式碼
四、任意兩個元件之間的資料傳遞
1、使用VueX
Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,
Vuex 的狀態儲存是響應式的。當 Vue 元件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的元件也會相應地得到高效更新。
2、建立一個事件中心進行全域性傳遞與接受事件
建立一個事件中心Hub,相當於中轉站,可以用它來進行全域性傳遞事件和接收事件。
<div id="demo5">
<one-div></one-div>
<other-div></other-div>
</div>
var Hub = new Vue(); //建立事件中心,注意Hub要放在全域性
Vue.component("one-div",{
template : `
<div>
<p @click="sendMessage">向另外一個元件傳送訊息</p>
</div>
`,
methods : {
sendMessage : function(){
Hub.$emit("change","我是來自另外一個元件的訊息");
}
}
})
Vue.component("other-div",{
template : `
<div>
<p>{{ message }}</p>
</div>
`,
data : function(){
return {message : "這裡顯示的我自己元件的訊息"}
},
created(){
Hub.$on("change",(val) =>{
this.message = val;
})
}
})
new Vue({
el : "#demo5"
})
複製程式碼