【问题标题】:Vue.js - multiple event with dynamic componentsVue.js - 具有动态组件的多个事件
【发布时间】:2017-12-19 14:24:57
【问题描述】:

我有一个简单的根App,其中包括两个不同的组件RoomMachine。并且这些组件中的每一个都包含一个组件Datatable,这对它们来说都是完全相同的。要在RoomMachine 之间切换,我使用的是动态组件机制,没什么特别的。当组件发生变化时,我只发出事件,组件Datatable 应该使用当前模块名称将其记录到控制台中。问题是每次我更改组件时,都会多次发送事件。如果我理解正确,在更改组件后应该销毁旧组件并创建新组件,为什么会发生这种情况?我正在使用 Vue.js v.2.4.1

这是我在组件之间切换时来自控制台的屏幕截图:

这里是组件:

App.vue:

<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>

【问题讨论】:

    标签: javascript events vue.js vuejs2 vue-component


    【解决方案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/vue@2.2.6/dist/vue.js"></script>
    <div id="app">
    
    </div>

    【讨论】:

      猜你喜欢
      • 2019-10-07
      • 2019-04-05
      • 2020-02-06
      • 1970-01-01
      • 2017-11-29
      • 2018-02-20
      • 2017-12-18
      • 1970-01-01
      • 2018-11-21
      相关资源
      最近更新 更多