2016-12-01 3 views
1

私はthis質問/回答を読んで、そして親が特定のコンポーネントが含まれているときには機能しながら、私のシナリオでは、親がこの含まれていますヴュー2と子コンポーネントイベント

<component :is="currentView"></component> 

currentViewの値は、特定の時刻にどのコンポーネントが「ロード」されているかを決定します。したがって、コンポーネントタグのv-on:event="handler"を使用すると、ここではを意味します。子コンポーネントは同じイベント名を使用する必要があります:(親コンポーネントのcreated()機能では、現在どのコンポーネントが ' 「ログイン」イベントを送信するログインコンポーネントと、「更新」イベントを送信するデータビューコンポーネントがあります。親では、次のようなものが必要ですこの:

this.$on('login', doLogin) 
this.$on('update', doUpdate) 

は、しかし、それはその子供ではない、自体からのイベントに耳を傾けています、私はまた、コンポーネントに参照を与えてみました:。

<component ref="main" :is="currentView"></component> 

this.$refs.main.$on('login', doLogin)を使用しますが、初期には、レンダリングまでmounted()方法(早すぎる)に行くことができない、とupdated()方法でそれが繰り返し呼び出されるように$refsオブジェクトは、作成されていませんこれは、私は確信して良いアイデアではありません...

答えて

2

あなたは、グローバルイベントを設定し、ペイロードの一部として、アクションの名前を渡すことができ、すなわち

const Login = { 
 
    template: `<h1>Login</h1>`, 
 
    mounted() { 
 

 
    this.$emit('global-event', { 
 
     action: 'login', 
 
     data: { 
 
     user: 'foo', 
 
     }, 
 
    }) 
 

 
    }, 
 
} 
 

 
const Update = { 
 
    template: `<h1>Update</h1>`, 
 
    mounted() { 
 

 
    this.$emit('global-event', { 
 
     action: 'update', 
 
     data: { 
 
     user: 'foo bar', 
 
     }, 
 
    }) 
 

 
    }, 
 
} 
 

 

 
new Vue({ 
 
    el: '#app', 
 
    data: { 
 
    called: { 
 
     update: 0, 
 
     login: 0, 
 
    }, 
 
    currentView: 'login', 
 
    }, 
 
    components: { 
 
    Login, 
 
    Update, 
 
    }, 
 
    methods: { 
 
    
 
    // within doSomething you would process the various events based on their payload.action 
 
    doSomething (payload) { 
 
     
 
     this.called[payload.action]++ 
 
     
 
    }, 
 
     
 
    toggleView() { 
 
     
 
     this.currentView = this.currentView === 'login' ? 'update' : 'login' 
 
     
 
    }, 
 
    
 
    }, 
 
})
<script src="https://unpkg.com/vue/dist/vue.js"></script> 
 
<div id="app"> 
 
    <component @global-event="doSomething" :is="currentView"></component> 
 
    <button @click="toggleView">toggle view</button> 
 
    <pre>{{ called }}</pre> 
 
</div>

+0

はい、それは私が「すべての子コンポーネントは同じイベント名を使用する必要があります」という質問の意味です。私は正直言って、ハンドラのアプローチが嫌いです。保守がもっと複​​雑です。しかし、あなたがすべての子コンポーネントをコントロールしているとき、私がより良い選択肢だと思うものについて、私の答えを見てください。 – dsl101

0

Gah!検索年齢を過ごした後、何も見つけずにここに投稿すると、私はすぐに答えにつきまとう。

しかし、の場合は(私はすべてをビルドしています)の子コンポーネントを管理している場合にのみ適用されます。子供では、単にあなた:そして

this.$parent.$emit('login', {some: 'data'}) 

とはcreated()方法では、通常、親にthis.$on('login', doLogin)でイベントリスナーを設定します。

私は、単にthis.$emit()を呼び出す第三者コンポーネントを使用しているシナリオがあると確信しています。現時点では、親にv-on:eventName="handler"の代替手段はありません。

+0

これはオプションですが、一般的に他のVM上でイベント/セットパラメータを起動することはお勧めしません。あなたがそれを避けることができれば、あなたはコンポーネントを切り離すことができます:https://vuejs.org/v2/guide/components.html#Using-v-on-with-Custom-Events – GuyC

+0

私は同意します。それが作成するイベントのセット、それは火災と(それを無視することを選択することができます)親と忘れて、ほとんどの違いはないと思われる親は、明示的に子供の上でそれを聞いています。そして、私の場合、同じイベント名を使用する必要があるので、私のコンポーネントを互いに結合する、v-onなしでこれを行う方法はないようです。 – dsl101

関連する問題