2017-07-11 45 views
2

2つのコンポーネントを動的にレンダリングする必要がある単純なアプリケーションがあります。vue.jsの動的コンポーネントの操作

  • 成分Aは - onClickイベントを持っている必要があります。
  • コンポーネントB - onChangeイベントが必要です。

異なるイベントをコンポーネントA/Bにどのように動的に取り付けることができますか?

<template> 
    <component v-bind:is="currentView"> 
    </component> 
</template> 

<script> 
import A from '../components/a.vue' 
import B from '../components/b.vue' 

export default { 
    data: function() { 
    return { 
     currentView: A 
    } 
    }, 
    components: { A, B } 
} 
</script> 

答えて

4

はもう少し複雑で現実的なユースケースのためのソリューションです。このユースケースでは、v-forを使用して複数の異なるコンポーネントをレンダリングする必要があります。

親コンポーネントは、コンポーネントの配列をcreate-componentsに渡します。 create-componentsは、このアレイでv-forを使用し、正しいイベントですべてのコンポーネントを表示します。

私はこの動作を実現するためにカスタムディレクティブcustom-eventsを使用しています。

parent

<template> 
    <div class="parent"> 
     <create-components :components="components"></create-components> 
    </div> 
</template> 

<script> 
import CreateComponents from '@/components/CreateComponents' 
import ComponentA from '@/components/ComponentA' 
import ComponentB from '@/components/ComponentB' 

export default { 
    name: 'parent', 
    data() { 
     return { 
      components: [ 
       { 
        is: ComponentA, 
        events: { 
         "change":this.componentA_onChange.bind(this) 
        } 
       }, 
       { 
        is: ComponentB, 
        events: { 
         "click":this.componentB_onClick.bind(this) 
        } 
       } 
      ] 
     } 
    }, 
    methods: { 
     componentA_onChange() { 
      alert('componentA_onChange'); 
     }, 
     componentB_onClick() { 
      alert('componentB_onClick'); 
     } 
    }, 
    components: { CreateComponents } 
}; 
</script> 

create-components

<template> 
    <div class="create-components"> 
     <div v-for="(component, componentIndex) in components"> 
      <component v-bind:is="component.is" v-custom-events="component.events"></component> 
     </div> 
    </div> 
</template> 

<script> 
export default { 
    name: 'create-components', 
    props: { 
     components: { 
      type: Array 
     } 
    }, 
    directives: { 
     CustomEvents: { 
      bind: function (el, binding, vnode) { 
       let allEvents = binding.value; 
       if(typeof allEvents !== "undefined"){ 
        let allEventsName = Object.keys(binding.value); 
        allEventsName.forEach(function(event) { 
         vnode.componentInstance.$on(event, (eventData) => { 
          allEvents[event](eventData); 
         }); 
        }); 
       } 
      }, 
      unbind: function (el, binding, vnode) { 
       vnode.componentInstance.$off(); 
      } 
     } 
    } 
    } 
</script> 
1

動的に追加する必要はありません。

<component v-bind:is="currentView" @click="onClick" @change="onChange"> 

あなたが慎重になりたい場合は、currentViewのハンドラ内で救済することができます正しくありません。ここで

methods: { 
    onClick(){ 
    if (this.currentView != A) return 
    // handle click 
    }, 
    onChange(){ 
    if (this.currentView != B) return 
    // handle change 
    } 
} 
+0

それは良いアプローチ、感謝です! – LiranC

関連する問題