使用 eventHub 在 Vue 中发出事件的问题

Ash*_*ett 6 javascript events vue.js

我有一个组件需要在其生命周期的某个时刻发出一个事件。此事件将由同级组件侦听。

我正在使用事件中心进行此通信。

但是,我Uncaught TypeError在尝试调用eventHub.$emit('EventName').

这是控制台中收到的完整错误。

vue.js?3de6:2400 Uncaught TypeError: cbs[i].apply is not a function
at Vue$3.Vue.$emit (eval at <anonymous> (http://rounds.smaa.app:8000/js/app.js:322:1), <anonymous>:2400:16)
at Vue$3.e.(anonymous function) [as $emit] (chrome-extension://nhdogjmejiglipccpnnnanhbledajbpd/build/backend.js:1:6235)
at VueComponent.importPlayers (eval at <anonymous> (http://rounds.smaa.app:8000/js/app.js:178:1), <anonymous>:98:64)
at Proxy.boundFn (eval at <anonymous> (http://rounds.smaa.app:8000/js/app.js:322:1), <anonymous>:130:14)
at Object.change [as fn] (eval at <anonymous> (http://rounds.smaa.app:8000/js/app.js:261:1), <anonymous>:118:13)
at HTMLInputElement.eval (eval at <anonymous> (http://rounds.smaa.app:8000/js/app.js:322:1), <anonymous>:2229:16)
Run Code Online (Sandbox Code Playgroud)

这是导致错误的代码:

importPlayers(e) {

    eventHub.$emit('AdminAddedPlayers');

    this.importing = true;
    this.success.import = false;
    ...
    ...
}
Run Code Online (Sandbox Code Playgroud)

该组件似乎没有任何其他问题,但这里是完整的组件和 eventHub:

资产/js/components/Admin/AdminImportPlayersComponent

<template>
<div class="component">
    <!-- removed some boilerplate markup for brevity -->

    <template v-if="! importing && ! warning.invalid_data_submitted">
        <h4>Import Players</h4>
        <div class="form-group" :class="error.import ? 'has-error' : ''">
            <input type="file" @change="importPlayers($event)" id="file" class="form-control">
            <div v-if="error.import" class="help-block danger">
                You need to select a valid excel file.
            </div>
        </div>
    </template>
</div>
</template>

<script>
import eventHub from '../../../events.js';
export default {
    data() {
        return {
            importing: false,
            error: {
                import: false,
                other: false,
            },
            warning: {
                invalid_data_submitted: false,
                invalid_fixed_data_submitted: false
            },
            success: {
                import: false
            },
            invalid_players: [],
            teams: [],
            loader_color: '#0d0394'
        }
    },
    methods: {
        importPlayers(e) {

            eventHub.$emit('AdminAddedPlayers');

            this.importing = true;
            this.success.import = false;

            var formData = new FormData();
            formData.append('players', e.target.files[0]);

            return this.$http.post('/admin/players/import', formData).then((response) => {
                if (response.data.invalid_player_data.length) {
                    this.invalid_players = response.data.invalid_player_data;
                    this.warning.invalid_data_submitted = true;
                    this.getTeams();
                } else {
                    this.success.import = true;
                }
                this.importing = false;
                this.error.import = false;
                this.error.other = false;
            }, (response) => {
                if (response.data.players) {
                    this.error.import = true;
                } else {
                    this.error.other = true;
                }
                this.importing = false;
                this.warning.invalid_data_submitted = false;
                this.success.import = false;
            });
        },
        submitFixedPlayers() {

            eventHub.$emit('AdminAddedPlayers');

            this.importing = true;

            return this.$http.post('/admin/players/import/fixed', {
                players: this.invalid_players
            }).then((response) => {
                // conditionals


            }, (response) => {
                this.importing = false;
            });
        },
        getTeams() {
            return this.$http.get('/admin/teams/fetch').then((response) => {
                // team stuff
            });
        },
        setDefaultTeams() {
            // setting default teams
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

资产/js/events.js

module.exports = new Vue()
Run Code Online (Sandbox Code Playgroud)

Vue 源码指向 Vue 中的这段代码:

Vue.prototype.$emit = function (event) {
    var vm = this;
    var cbs = vm._events[event];
    if (cbs) {
        cbs = cbs.length > 1 ? toArray(cbs) : cbs;
        var args = toArray(arguments, 1);
        for (var i = 0, l = cbs.length; i < l; i++) {
          cbs[i].apply(vm, args);
        }
      }
    return vm
  };
Run Code Online (Sandbox Code Playgroud)

Ash*_*ett 5

解决方案

$on用于监听由 发出的事件时eventHub,我发现您不能传入参数,如下所示:

vm.$on('Event', this.callback(arg1));
Run Code Online (Sandbox Code Playgroud)

这似乎抛出了一个TypeError.

文档提到传递给 的任何参数$emit,如下所示:

vm.$emit('Event', args);
Run Code Online (Sandbox Code Playgroud)

会自动传入$on回调。

所以下面的代码是正确的(对我有用):

vm.$emit('AdminAddedPlayers', 1)

vm.$on('AdminAddedPlayers', this.callback);
Run Code Online (Sandbox Code Playgroud)

执行时,callbackfrom的调用$on类似于:

this.callback(arg);
Run Code Online (Sandbox Code Playgroud)

从哪里arg传入$emit