javascript - VueJS 组件发出重复事件

标签 javascript vue.js vuejs2 event-bus vue-devtools

当我的鼠标光标进入和离开我的 VueJS 组件时,分别调用以下方法。

当光标进入和离开我的组件时调用的方法:

// located in "methods" section of my Vue component file

onMouseEnter() {
    window.Event.$emit("mouse-entered", this.index);
    console.log("Mouse entered");
},
onMouseLeave() {
    window.Event.$emit("mouse-left", this.index);
    console.log("Mouse left");
},

这就是我的控制台在我的光标进入和离开组件时的样子(每次发出一个事件):

enter image description here

然而,真正奇怪的是,在 Vue 开发工具中,每次我的光标进入和离开我的组件时,我都会看到重复的事件:

enter image description here

鉴于这些相互矛盾的信息,我不确定该相信什么。 有时刷新页面会消除开发工具中的重复事件,但我总是在我的控制台中获得单一、独特的事件,这是我想要的行为。

有谁知道这里发生了什么,我应该接受什么作为真相的来源?

下面是我的 Vue 实例是如何在我的 main.js 文件中声明和初始化的:

// As far as I can tell, duplicated Vue instances are not being created here on page refresh

let app;

// global event bus
window.Event = new Vue();
console.log("Event bus created");

/* This section ensures the firebase auth object isn't in an intermediary state. */
firebase.auth().onAuthStateChanged(() => {
    if (!app) {
        console.log("New Vue instance created");
        app = new Vue({
            el: '#app',
            router,
            store,
            render: h => h(App)
        });
    }
});

请注意,此特定组件在两个不同的路由(“dashboard”和“home”)上重复使用,它们都通过以下代码保持事件状态。

// Template section of App.vue file
<template>
    <div id="app">
        <keep-alive
            v-bind:include="[ 'dashboard', 'home' ]"
            <router-view></router-view>
        </keep-alive>
    </div>
</template>

此外,由于这两个路由保持事件状态并被缓存,未能关闭 $off 事件发射器和监听器不应该是重复的原因(至少我认为不应该)。

编辑 1: 我在项目的每个目录中都查找了“鼠标输入”和“鼠标左键”,我可以确认这两个事件都仅从 Vue 发出我在这篇文章中提到的组件。

编辑 2: 为了帮助调试,我在最顶层的组件 (App.vue) 上放置了一个监听器,以查看它是否两次接收到事件(请参阅代码中创建的 Hook 下面的片段)。 我可以确认它也只接收一次事件。我还粘贴了我完整的 App.vue 文件,因为上面的例子主要是为了说明我保持事件的“仪表板”和“主页” ".

<template>
    <div id="app">
        <keep-alive
            v-bind:include="keepAlive">
            <router-view></router-view>
        </keep-alive>
    </div>
</template>

<script>
    export default {
        name: 'app',
        data() {
            return {
                isLoggedIn: false,
            };
        },
        computed: {
            keepAlive() {
                if (this.isLoggedIn) {
                    return [ 'dashboard', 'home', 'results' ];
                }
                return [ 'landing', 'signIn', 'signUp' ];
            }
        },
        watch: {
            /* This watches for route changes */
            $route(to, from) {
                /* firebase.auth().currentUser returns null if user has logged out */
                if (firebase.auth().currentUser) {
                    this.isLoggedIn = true;
                } else {
                    this.isLoggedIn = false;
                }
            }
        },
        created() {
            window.Event.$on("mouse-entered", () => {
                console.log("mouse-entered-from-App.vue");
            });
            window.Event.$on("mouse-left", () => {
                console.log("mouse-left-from-App.vue");
            });
        }
    };
</script>

正如预期的那样,App.vue 收到一次事件(见下文);但是,我仍然在 Vue 开发工具中收到重复事件:(

enter image description here

最佳答案

你写了

Refreshing the page sometimes eliminates the duplicate events in dev tools but I always get single, unique events in my console, which is my desired behaviour.

您描述问题的方式正确地发出了事件,同时以错误的重复方式对事件做出了 react 。 我认为您可能缺少的是一旦组件被销毁就取消订阅您的事件总线。您应该使用 beforeDestroy Hook 来执行此操作(类似于您在组件生命周期早期使用 created 进行订阅的方式)。

像这样:

beforeDestroy() {
    window.Event.$off('mouse-entered');
    window.Event.$off('mouse-left');
}

关于javascript - VueJS 组件发出重复事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51457160/

相关文章:

javascript - 如何在 Vue.js 中创建独立运行的动态行?

javascript - Vue 和带模板标签的条件渲染

Javascript 积分计算器无法正常工作(HTML 选择/选项 + Javascript)

javascript - 有序列表仅获取子项

javascript - vue.js 和 firebase 查询给出错误的数组计数

javascript - VueJS v-for 对象不显示键

vue.js - Vuejs : Lifecycle hooks of child routerview components using keep alive

javascript - 在Javascript中遍历DOM(nodeType)

javascript - 从 Chrome 扩展程序的存储中请求数据

vue.js - 在其他条件类之上应用 vue.js 中计算的动态 CSS 类