vueコンポーネント間通信方式例まとめ【8方式】

10388 ワード

この例ではvueコンポーネント間の通信方式をまとめた.皆さんの参考にしてください.具体的には以下の通りです.
vueにとって、コンポーネント間のメッセージングは非常に重要であり、以下は私がコンポーネント間のメッセージングの様々な方法の総括であり、全部で8つの方法がある.
1.propsと$emit
親コンポーネントから子コンポーネントへのデータの転送はpropによって行われ、子コンポーネントから親コンポーネントへのデータの転送は$emitトリガイベントによって行われます.

Vue.component('child',{
    data(){
      return {
        mymessage:this.message
      }
    },
    template:`
      
`, props:['message'],// methods:{ passData(val){ // this.$emit('getChildData',val) } } }) Vue.component('parent',{ template:`

this is parent compoent!

`, data(){ return { message:'hello' } }, methods:{ // getChildData(val){ console.log(val) } } }) var app=new Vue({ el:'#app', template:`
` })

上記の例では、親コンポーネントparentとサブコンポーネントchildがあります.
1).親コンポーネントはメッセージデータをサブコンポーネントに渡し、v-onによってgetChildDataイベントをバインドしてサブコンポーネントのトリガイベントを傍受する.
2).サブコンポーネントはpropsによって関連するmessageデータを得、最後にthis.$emitによってgetChildDataイベントをトリガする.
2.$attrsと$listeners
1つ目の方法は、親コンポーネントAの下にサブコンポーネントBがあり、コンポーネントBの下にコンポーネントCがある場合、コンポーネントAがコンポーネントCにデータを伝えたい場合、どのようにしますか?
第1の方法を採用する場合、コンポーネントAはpropを通じてコンポーネントBにメッセージを伝達し、コンポーネントBはpropを通じてコンポーネントCにメッセージを伝達しなければならない.コンポーネントAとコンポーネントCの間により多くのコンポーネントがある場合、この方法では複雑です.Vue 2.4は、この問題を解決するために$attrsと$listenersを提供し始め、コンポーネントA間でコンポーネントCにメッセージを伝達することができる.

Vue.component('C',{
    template:`
      
`, methods:{ passCData(val){ // A this.$emit('getCData',val) } } }) Vue.component('B',{ data(){ return { mymessage:this.message } }, template:`
`, props:['message'],// methods:{ passData(val){ // this.$emit('getChildData',val) } } }) Vue.component('A',{ template:`

this is parent compoent!

`, data(){ return { message:'hello', messagec:'hello c' // c } }, methods:{ getChildData(val){ console.log(' B ') }, // C getCData(val){ console.log(" C :"+val) } } }) var app=new Vue({ el:'#app', template:`
` })

3.中央イベントバス
上記の2つの方法は、親子コンポーネント間のデータ伝達を処理していますが、2つのコンポーネントが親子関係ではない場合は?この場合、中央イベントバスの方式を使用することができる.Vueイベントbusオブジェクトを新規作成し、bus.$emitによってイベントをトリガーし、bus.$onによってトリガーされたイベントをリスニングします.

Vue.component('brother1',{
    data(){
      return {
        mymessage:'hello brother1'
      }
    },
    template:`
      

this is brother1 compoent!

`, methods:{ passData(val){ // globalEvent bus.$emit('globalEvent',val) } } }) Vue.component('brother2',{ template:`

this is brother2 compoent!

brother1 :{{brothermessage}}

`, 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:`
` })

4.provideとinject
親コンポーネントではproviderによって変数が提供され、サブコンポーネントではinjectによって変数が注入されます.サブコンポーネントの深さにかかわらず、injectを呼び出すだけでproviderのデータを注入できます.現在の親コンポーネントのpropプロパティからのみデータを取得できるのではなく、親コンポーネントのライフサイクル内にサブコンポーネントが呼び出される限りです.

Vue.component('child',{
    inject:['for'],//            
    data(){
      return {
        mymessage:this.for
      }
    },
    template:`
      
}) Vue.component('parent',{ template:`

this is parent compoent!

`, provide:{ for:'test' }, data(){ return { message:'hello' } } }) var app=new Vue({ el:'#app', template:`
` })

5. v-model
親コンポーネントがv-modelを介してサブコンポーネントに値を渡すと、valueのpropプロパティが自動的に渡され、サブコンポーネントではthis.$emit(‘input',val)を介してv-modelバインドの値が自動的に変更されます.

Vue.component('child',{
    props:{
      value:String, //v-model          value prop  
    },
    data(){
      return {
        mymessage:this.value
      }
    },
    methods:{
      changeValue(){
        this.$emit('input',this.mymessage);//              v-model    
      }
    },
    template:`
      
}) Vue.component('parent',{ template:`

this is parent compoent!

{{message}}

`, data(){ return { message:'hello' } } }) var app=new Vue({ el:'#app', template:`
` })

6.$parentと$children

Vue.component('child',{
    props:{
      value:String, //v-model          value prop  
    },
    data(){
      return {
        mymessage:this.value
      }
    },
    methods:{
      changeValue(){
        this.$parent.message = this.mymessage;//               
      }
    },
    template:`
      
}) Vue.component('parent',{ template:`

this is parent compoent!

`, methods:{ changeChildValue(){ this.$children[0].mymessage = 'hello'; } }, data(){ return { message:'hello' } } }) var app=new Vue({ el:'#app', template:`
` })

7.boradcastとdispatch
vue1.0ではこのような方法が提供するが、vue 2.0にはありませんが、min ui、element ui、iviewなど、多くのオープンソースソフトウェアが独自にパッケージされています.
例えば、broadcastは特定の親コンポーネント、トリガイベント、dispatchは特定のサブコンポーネントにイベントをトリガし、本質的にはonとonとemitのパッケージであるが、いくつかの基礎コンポーネントでは実用的である.

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)) {
    parent = 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処理コンポーネント間のデータインタラクション
ビジネスロジックが複雑な場合、多くのコンポーネントの間で共通のデータを同時に処理する必要があります.この場合、上記の方法はプロジェクトのメンテナンスに不利になる可能性があります.vuexの方法は、これらの共通のデータを抽出し、他のコンポーネントがこの共通のデータを読み書き操作することで、デカップリングの目的を達成します.
詳細は以下を参照してください.https://vuex.vuejs.org/zh-cn/
本文で述べたようにみんなにvue.jsプログラム設計が役立ちます.