溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

vue中有哪些組件通信方式

發(fā)布時(shí)間:2021-07-09 11:03:24 來源:億速云 閱讀:168 作者:Leah 欄目:web開發(fā)

這篇文章將為大家詳細(xì)講解有關(guān)vue中有哪些組件通信方式,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

1. props和$emit

這是最最常用的父子組件通信方式,父組件向子組件傳遞數(shù)據(jù)是通過prop傳遞的,子組件傳遞數(shù)據(jù)給父組件是通過$emit觸發(fā)事件來做到的。 實(shí)例:

父組件

Vue.component('parent',{  template:`  <div>  <p>父組件</p>  <child :message="message" v-on:getChildData="getChildData"></child>  </div>  `,  data(){  return {  message:'Hello web秀'  }  },  methods:{  //執(zhí)行子組件觸發(fā)的事件  getChildData(val){  console.log(val)  }  } }) var app=new Vue({  el:'#app',  template:`  <div>  <parent></parent>  </div>  ` })

子組件

Vue.component('child',{  //得到父組件傳遞過來的數(shù)據(jù)  props:['message'],  data(){  return {  myMessage: this.message  }  },  template:`  <div>  <input type="text" v-model="myMessage" @input="passData(myMessage)">   </div>  `,  methods:{  passData(val){  //觸發(fā)父組件中的事件  this.$emit('getChildData',val)  }  } })

解析:

  • 父組件傳遞了message數(shù)據(jù)給子組件,并且通過v-on綁定了一個(gè)getChildData事件來監(jiān)聽子組件的觸發(fā)事件;

  • 子組件通過props得到相關(guān)的message數(shù)據(jù),***通過this.$emit觸發(fā)了getChildData事件。

2. $attrs和$listeners

***種方式處理父子組件之間的數(shù)據(jù)傳輸有一個(gè)問題:如果多層嵌套,父組件A下面有子組件B,組件B下面有組件C,這時(shí)如果組件A想傳遞數(shù)據(jù)給組件C怎么辦呢?

如果采用***種方法,我們必須讓組件A通過prop傳遞消息給組件B,組件B在通過prop傳遞消息給組件C;要是組件A和組件C之間有更多的組件,那采用這種方式就很復(fù)雜了。從Vue  2.4開始,提供了$attrs和$listeners來解決這個(gè)問題,能夠讓組件A之間傳遞消息給組件C。

C組件

Vue.component('C',{  template:`  <div>  <input type="text" v-model="$attrs.messageC" @input="passCData($attrs.messageC)">  </div>  `,  methods:{  passCData(val){  //觸發(fā)父組件A中的事件  this.$emit('getCData',val)  }  } })

B組件

Vue.component('B',{  data(){  return {  myMessage:this.message  }  },  template:`  <div>  <input type="text" v-model="myMessage" @input="passData(myMessage)">  <C v-bind="$attrs" v-on="$listeners"></C>  </div>  `,  //得到父組件傳遞過來的數(shù)據(jù)  props:['message'],  methods:{  passData(val){  //觸發(fā)父組件中的事件  this.$emit('getChildData',val)  }  } })

A組件

Vue.component('A',{  template:`  <div>  <p>this is parent compoent!</p>  <B   :messageC="messageC"   :message="message"   v-on:getCData="getCData"   v-on:getChildData="getChildData(message)">  </B>  </div>  `,  data(){  return {  message:'Hello',  messageC:'Hello c'  }  },  methods:{  getChildData(val){  console.log('這是來自B組件的數(shù)據(jù)')  },  //執(zhí)行C子組件觸發(fā)的事件  getCData(val){  console.log("這是來自C組件的數(shù)據(jù):"+val)  }  } }) var app=new Vue({  el:'#app',  template:`  <div>  <A></A>  </div>  ` })

解析:

  • C組件中能直接觸發(fā)getCData的原因在于 B組件調(diào)用C組件時(shí) 使用 v-on 綁定了$listeners 屬性

  • 通過v-bind 綁定$attrs屬性,C組件可以直接獲取到A組件中傳遞下來的props(除了B組件中props聲明的)

vue中有哪些組件通信方式

3. v-model

父組件通過v-model傳遞值給子組件時(shí),會自動傳遞一個(gè)value的prop屬性,在子組件中通過this.$emit(&lsquo;input',val)自動修改v-model綁定的值

子組件

Vue.component('child',{  props:{  //v-model會自動傳遞一個(gè)字段為value的prop屬性  value: String,   },  data(){  return {  myMessage:this.value  }  },  methods:{  changeValue(){  //通過如此調(diào)用可以改變父組件上v-model綁定的值  this.$emit('input',this.myMessage);  }  },  template:`  <div>  <input   type="text"   v-model="myMessage"   @change="changeValue">  </div>  ` })

父組件

Vue.component('parent',{  template:`  <div>  <p>this is parent compoent!</p>  <p>{{message}}</p>  <child v-model="message"></child>  </div>  `,  data(){  return {  message:'Hello'  }  } }) var app=new Vue({  el:'#app',  template:`  <div>  <parent></parent>  </div>  ` })

4. provide和inject

父組件中通過provider來提供變量,然后在子組件中通過inject來注入變量。不論子組件有多深,只要調(diào)用了inject那么就可以注入provider中的數(shù)據(jù)。而不是局限于只能從當(dāng)前父組件的prop屬性來獲取數(shù)據(jù),只要在父組件的生命周期內(nèi),子組件都可以調(diào)用。

子組件

Vue.component('child',{  inject:['for'],//得到父組件傳遞過來的數(shù)據(jù)  data(){  return {  myMessage: this.for  }  },  template:`  <div>  <input type="tet" v-model="myMessage">  </div>  ` })

父組件

Vue.component('parent',{  template:`  <div>  <p>this is parent compoent!</p>  <child></child>  </div>  `,  provide:{  for:'test'  },  data(){  return {  message:'Hello'  }  } }) var app=new Vue({  el:'#app',  template:`  <div>  <parent></parent>  </div>  ` })

5. 中央事件總線

上面方式都是處理的父子組件之間的數(shù)據(jù)傳遞,那如果兩個(gè)組件不是父子關(guān)系呢?也就是兄弟組件如何通信?

這種情況下可以使用中央事件總線的方式。新建一個(gè)Vue事件bus對象,然后通過bus.$emit觸發(fā)事件,bus.$on監(jiān)聽觸發(fā)的事件。

Vue.component('brother1',{  data(){  return {  myMessage:'Hello brother1'  }  },  template:`  <div>  <p>this is brother1 compoent!</p>  <input type="text" v-model="myMessage" @input="passData(myMessage)">  </div>  `,  methods:{  passData(val){  //觸發(fā)全局事件globalEvent  bus.$emit('globalEvent',val)  }  } }) Vue.component('brother2',{  template:`  <div>  <p>this is brother2 compoent!</p>  <p>brother1傳遞過來的數(shù)據(jù):{{brothermessage}}</p>  </div>  `,  data(){  return {  myMessage:'Hello brother2',  brothermessage:''  }  },  mounted(){  //綁定全局事件globalEvent  bus.$on('globalEvent',(val)=>{  this.brothermessage=val;  })  } }) //中央事件總線 var bus=new Vue(); var app=new Vue({  el:'#app',  template:`  <div>  <brother1></brother1>  <brother2></brother2>  </div>  ` })

vue中有哪些組件通信方式

6. parent和children

Vue.component('child',{     props:{       value:String, //v-model會自動傳遞一個(gè)字段為value的prop屬性     },     data(){       return {         mymessage:this.value       }     },     methods:{       changeValue(){         this.$parent.message = this.mymessage;//通過如此調(diào)用可以改變父組件的值       }     },     template:`       <div>         <input type="text" v-model="mymessage" @change="changeValue">       </div>   })   Vue.component('parent',{     template:`       <div>         <p>this is parent compoent!</p>         <button @click="changeChildValue">test</button >         <child></child>       </div>     `,     methods:{       changeChildValue(){         this.$children[0].mymessage = 'hello';       }//在此我向大家推薦一個(gè)前端全棧開發(fā)交流圈:619586920 突破技術(shù)瓶頸,提升思維能力     },     data(){       return {         message:'hello'       }     }   })   var app=new Vue({     el:'#app',     template:`       <div>         <parent></parent>       </div>     `   })

7. boradcast和dispatch

vue1.0中提供了這種方式,但vue2.0中沒有,但很多開源軟件都自己封裝了這種方式,比如min ui、element ui和iview等。  比如如下代碼,一般都作為一個(gè)mixins去使用,  broadcast是向特定的父組件,觸發(fā)事件,dispatch是向特定的子組件觸發(fā)事件,本質(zhì)上這種方式還是on和on和emit的封裝,但在一些基礎(chǔ)組件中卻很實(shí)用。

function broadcast(componentName, eventName, params) {  this.$children.forEach(child => {  var name = child.$options.componentName;  if (name === componentName) {  child.$emit.apply(child, [eventName].concat(params));  } else {  broadcast.apply(child, [componentName, eventName].concat(params));  }  }); } export default {  methods: {  dispatch(componentName, eventName, params) {  var parent = this.$parent;  var name = parent.$options.componentName;  while (parent && (!name || name !== componentName)) {  parentparent = parent.$parent;  if (parent) {  name = parent.$options.componentName;  }  }  if (parent) {  parent.$emit.apply(parent, [eventName].concat(params));  }  },  broadcast(componentName, eventName, params) {  broadcast.call(this, componentName, eventName, params);  }  } };

8. vuex處理組件之間的數(shù)據(jù)交互

如果業(yè)務(wù)邏輯復(fù)雜,很多組件之間需要同時(shí)處理一些公共的數(shù)據(jù),這個(gè)時(shí)候才有上面這一些方法可能不利于項(xiàng)目的維護(hù),vuex的做法就是將這一些公共的數(shù)據(jù)抽離出來,然后其他組件就可以對這個(gè)公共數(shù)據(jù)進(jìn)行讀寫操作,這樣達(dá)到了解耦的目的。

關(guān)于vue中有哪些組件通信方式就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

vue
AI