2017-07-14 21 views
1

私は、2つの異なるコンポーネントRoomMachineを含む単純なルートAppを持っています。これらのコンポーネントのそれぞれには、両方のコンポーネントが全く同じ1つのコンポーネントDatatableが含まれています。 RoomMachineの間を切り替えるには、私は動的コンポーネントのメカニズムを使用していますが、特別なことはありません。コンポーネントが変更されているとき、私はちょうどイベントとコンポーネントを発行します。Datatableは、現在のモジュール名でコンソールにログインする必要があります。問題は、コンポーネントを変更するたびに、イベントが複数回送信されることです。私が正しいことを理解していれば、コンポーネントを変更した後、古いものを破壊し、新しいものが作成されたので、なぜこれが起こっているのでしょうか?私はここでVue.jsのv.2.4.1Vue.js - 動的コンポーネントを含む複数のイベント

を使用しています私は、コンポーネント間の切り替え時にコンソールからのスクリーンショットです:

App.vue:

enter image description here

ここでは、コンポーネントです

<template> 
    <div id="app"> 
     <select style="padding: 10px" v-model="currentModule" @change="changeComponent"> 
      <option value="Room">Room</option> 
      <option value="Machine">Machine</option> 
     </select> 
     <component :is="currentModule"></component> 
    </div> 
</template> 

<script> 
    import Room from './Room.vue'; 
    import Machine from './Machine.vue'; 


    export default { 
     name: 'app', 
     components: { 
      Room, 
      Machine 
     }, 
     data() { 
      return { 
       currentModule: 'Room' 
      } 
     }, 
     methods: { 
      changeComponent: function() { 
       Event.$emit('moduleHasChanged', this.currentModule) 
      } 
     }, 
    } 
</script> 

Machine.vue:

<template> 
    <div> 
     Machine template 

     <datatable></datatable> 
    </div> 
</template> 
<script> 
    import Datatable from './Datatable.vue'; 

    export default { 
     components: { 
      Datatable 
     } 
    } 
</script> 

Room.vue:

<template> 
    <div> 
     Room template 

     <datatable></datatable> 
    </div> 
</template> 
<script> 
    import Datatable from './Datatable.vue'; 

    export default { 
     components: { 
      Datatable 
     } 
    } 
</script> 

Datatable.vue

<template> 
    <div> 
     Datatable 
    </div> 
</template> 

<script> 
    export default { 
     created() { 
      Event.$on('moduleHasChanged', (currentModule) => { 
       console.log(currentModule); 
      }) 
     } 
    } 
</script> 

答えて

1

あなたが継続的にイベントリスナーを追加する(Datatableコンポーネントが作成されたとき)と決して削除されていないので、これが起こっていますそれら。通常はVueがこれを処理しますが、イベントバスを使用しているので、自分で行う必要があります。

beforeDestroyハンドラを追加し、イベントハンドラを削除するだけです。

console.clear() 
 
const Event = new Vue() 
 

 
const Datatable = { 
 
    template: ` 
 
    <div> 
 
     Datatable 
 
    </div> 
 
    `, 
 
    methods: { 
 
    moduleChanged(currentModule) { 
 
     console.log(currentModule); 
 
    } 
 
    }, 
 
    created() { 
 
    Event.$on('moduleHasChanged', this.moduleChanged) 
 
    }, 
 
    beforeDestroy() { 
 
    Event.$off('moduleHasChanged', this.moduleChanged) 
 
    } 
 
} 
 

 
const Room = { 
 
    template: ` 
 
    <div> 
 
     Room template 
 
     <datatable></datatable> 
 
    </div> 
 
    `, 
 
    components: { 
 
    Datatable 
 
    } 
 
} 
 

 
const Machine = { 
 
    template: ` 
 
    <div> 
 
     Machine template 
 
     <datatable></datatable> 
 
    </div> 
 
    `, 
 
    components: { 
 
    Datatable 
 
    } 
 
} 
 

 
const App = { 
 
    name: 'app', 
 
    template: ` 
 
    <div id="app"> 
 
     <select style="padding: 10px" v-model="currentModule" @change="changeComponent"> 
 
      <option value="Room">Room</option> 
 
      <option value="Machine">Machine</option> 
 
     </select> 
 
     <component :is="currentModule"></component> 
 
    </div> 
 
    `, 
 
    components: { 
 
    Room, 
 
    Machine 
 
    }, 
 
    data() { 
 
    return { 
 
     currentModule: 'Room' 
 
    } 
 
    }, 
 
    methods: { 
 
    changeComponent: function() { 
 
     Event.$emit('moduleHasChanged', this.currentModule) 
 
    } 
 
    }, 
 
} 
 

 

 
new Vue({ 
 
    el: "#app", 
 
    render: h => h(App) 
 
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script> 
 
<div id="app"> 
 

 
</div>

関連する問題