組件化開(kāi)發(fā)最常見(jiàn)的業(yè)務(wù)場(chǎng)景就是組件之間的通信轩端,而vue并不能像react一樣凯亮,靈活的運(yùn)用
props
和回調(diào)函數(shù)就可以實(shí)現(xiàn)組件之間的通信恩商,vue提供相對(duì)較多的api應(yīng)對(duì)不同的功能需求倾鲫,這里做一個(gè)運(yùn)用層次的歸納,備忘郑气;
先模擬一個(gè)業(yè)務(wù)組件場(chǎng)景如下:
傳遞類(lèi)型見(jiàn)虛線字母(A幅垮、B……)
方式一:props
props
適合類(lèi)型A父?jìng)髯拥膫鬟f類(lèi)型;也是最常見(jiàn)的傳遞方式尾组;用法參見(jiàn)官方文檔忙芒;
方式二:$emit/$on
此方法適合ABCDEF所有傳遞類(lèi)型,父?jìng)髯踊淝取⒆觽鞲负侨⒖缃M件傳遞等;這里主要介紹一下兩種場(chǎng)景的使用方法
- 子傳父(B)主要通過(guò)
$emit
自定義事件發(fā)布事件跨跨,傳遞對(duì)應(yīng)參數(shù)潮峦,在父組件通過(guò)組件的屬性綁定對(duì)應(yīng)事件,接收對(duì)應(yīng)的參數(shù)勇婴; - 跨組件傳遞(all)主要是通過(guò)在
new Vue
實(shí)例對(duì)象上綁定中心事件忱嘹,然后廣播至各組件實(shí)現(xiàn);
以下模擬E路徑實(shí)現(xiàn)耕渴,其他相同
// componentE
var componentE = {
template:`
<h1 @click='cmeClick'>{{msge_}}</h1>
`,
data:function(){
return{
msge_:'componentE msg'
}
},
methods:{
cmeClick(){
// this.$root指向new vue實(shí)例對(duì)象
this.$root.$emit('componentE',this.msge_);
}
}
}
// componentB
var componentB = {
template:`
<h1>{{msge_}}</h1>
`,
data:function(){
return{
msge_:'componentB msg'
}
},
mounted() {
this.$root.$on('componentE',this.cme_emit)
},
methods:{
cme_emit(msg){
console.log(msg) //componentE msg
}
}
}
方式三:$attrs/$listeners
此方法常用于C路徑傳遞方式德谅,也就是祖?zhèn)髯樱?code>$attrs傳遞屬性,
$listeners
傳遞事件萨螺;因?yàn)?code>props傳遞只能之上而下一層一層傳遞窄做,并不能躍級(jí)傳遞,$attrs/$listeners
可以作為中間層將上層組件信息慰技,傳遞給任何子組件椭盏;
例子:首先
componentC
通過(guò)props
接收到componentA
組件信息;然后通過(guò)$attrs/$listeners
將接收到的信息傳遞給componentD
和componentE
;代碼如下:
var componentE = {
template:`
<h1 @click='cmeClick'>{{msge_}}</h1>
`,
mounted() {
console.log('cme:',this.$attrs,this.$listeners)
}
data:function(){
return{
msge_:this.msge
}
},
}
var componentD = {
template:`
<h1>{{msgd_}}</h1>
`,
mounted() {
console.log('cmd:',this.$attrs,this.$listeners)
},
data:function(){
return{
msgd_:this.msgd
}
}
}
var componentC = {
props:['msgc'], // `$attrs/$listeners`接收沒(méi)被props接收的屬性數(shù)據(jù)
template:`
<div>
<h1>{{msgc_}}</h1>
// 此處通過(guò)v-bind v-on 傳遞給需要的組件
<componentD :msgd='msgd' v-bind='$attrs' v-on='$listeners' />
<componentE :msgd='msgd' v-bind='$attrs' v-on='$listeners' />
</div>
`,
data:function(){
return{
msgc_:this.msgc,
msgd:'ddd',
msge:'eee'
}
},
components:{
componentD:componentD,
componentE:componentE
}
}
var componentA = {
template:`<div><componentC :b='b' @tb='tb' :msgc='msgc' /></div>`,
data:function(){
return{
msgc:'ccc',
b:0,
}
},
methods:{
cme_emit:function(msg){
console.log('cma:',msg)
},
tb(){
console.log(tb)
}
},
components:{
cmc:cmc
}
}
方式四:provide/inject
provide/inject
是從祖先組件想后代組件傳遞吻商,不論層次多深掏颊,但官方不推薦使用,這樣會(huì)破壞vue 數(shù)據(jù)流原則艾帐;使用方法很簡(jiǎn)單乌叶,祖組件定義provide
數(shù)據(jù),后代組件inject
接收柒爸;
var componentA = {
template:`<div>1111</div>`,
data:function(){
},
provide:{
testProvide:'provide data'
},
//……
}
var componentE = {
template:`
<h1'>2222</h1>
`,
inject:['testProvide'],
mounted() {
console.log(this.testProvide) //provide data
},
}
方式五 vuex
vuex是vue生態(tài)里面的狀態(tài)管理器准浴,可要儲(chǔ)存獲取項(xiàng)目任何數(shù)據(jù),詳見(jiàn)官網(wǎng)