programing

VueJS 구성 요소에서 중복 이벤트를 내보냅니다.

itsource 2022. 7. 28. 23:05
반응형

VueJS 구성 요소에서 중복 이벤트를 내보냅니다.

마우스 커서가 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");
},

예상대로 커서가 컴포넌트에 들어가거나 나갈 때 콘솔의 모양은 다음과 같습니다(각각 1개의 이벤트가 발생합니다).

여기서 이미지 설명을 입력하

하지만 정말 이상한 점은 Vue dev 툴에서 커서가 컴포넌트에 들어가거나 나갈 때마다 중복 이벤트가 발생한다는 것입니다.

여기서 이미지 설명을 입력하

이 상반된 정보로 인해 무엇을 믿어야 할지 잘 모르겠습니다.페이지를 새로 고치면 개발 도구에서 중복 이벤트가 제거될 수 있지만 항상 콘솔에 하나의 고유한 이벤트가 표시되므로 원하는 동작을 할 수 있습니다.

여기서 무슨 일이 일어나고 있는지, 진실의 근원으로서 무엇을 받아들여야 하는지 아는 사람 있나요?

Main.js 파일에서 Vue 인스턴스가 선언 및 초기화되는 방법은 다음과 같습니다.

// 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)
        });
    }
});

특정 컴포넌트는 다음 코드에 의해 활성화되어 있는2개의 다른 루트('대시보드''홈')에서 재사용되고 있습니다.

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

또한 이들 2개의 루트는 활성 상태로 유지되고 캐시되기 때문에 $이벤트 송신기와 리스너를 끄지 못한 것이 중복의 원인이 되어서는 안 됩니다(적어도 안 된다고 생각합니다).

편집 1: 프로젝트의 모든 디렉토리에서 "마우스 입력"과 "마우스 왼쪽"을 모두 검색했습니다.이 게시물에서 언급한 Vue 컴포넌트에서만 두 이벤트가 출력된다는 것을 확인할 수 있습니다.

편집 2: 디버깅을 지원하기 위해 청취자를 최상위 컴포넌트(App.vue)에 배치하여 이벤트를 두 번 수신하는지 확인합니다(아래 코드 스니펫에 작성된 후크를 참조하십시오).이벤트도 한 번만 받을 수 있습니다.또한 위의 예시는 주로 "대시보드"와 "홈"을 계속 사용하고 있음을 보여주기 위한 것이었기 때문에 전체 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 dev tools에서 중복 이벤트가 아직 수신됩니다.

여기서 이미지 설명을 입력하

네가 썼어

페이지를 새로 고치면 개발 도구에서 중복 이벤트가 제거될 수 있지만 항상 콘솔에 하나의 고유한 이벤트가 표시되므로 원하는 동작을 할 수 있습니다.

문제를 설명하는 방식으로 이벤트가 올바르게 전송되고 잘못된 중복된 방식으로 반응합니다.내 생각에 당신이 놓칠 수 있는 것은 컴포넌트가 파괴되면 당신의 이벤트 버스에서 구독을 취소하는 것이다.를 사용해야 합니다.beforeDestroy그렇게 하기 위한 후크(사용방법과 유사)created서브스크라이브하는 컴포넌트의 라이프 사이클 초기에).

다음과 같은 경우:

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

언급URL : https://stackoverflow.com/questions/51457160/duplicate-events-being-emitted-from-vuejs-component

반응형