Programing

공리 호출에 성공한 후 Vue.js 구성 요소가 상위 구성 요소로 방출되지 않음

c10106 2022. 5. 15. 07:24
반응형

공리 호출에 성공한 후 Vue.js 구성 요소가 상위 구성 요소로 방출되지 않음

나는 사용하고 있다

"axios": "^0.19.0",
"vue": "^2.6.10",
"vuex": "^3.1.1"

나의vuex동작은 다음과 같이 보이고 원격 인터페이스를 호출한다.axios그 요청은 효과가 있고 그것은 유효한 응답을 받는다.

skipQuestion({commit}, payload) {
    let params = {
        answer: {
            id: payload.id,
            skipped: true,
        }
    };

    return new Promise((resolve, reject) => {
        commit(UPDATE_LOADING, true);
        Remote.put(`/answer.json`, params)
            .then((response) => {
                commit(UPDATE_LOADING, false);
                commit(SKIP_QUESTION, payload.id);
                resolve();
            })
            .catch((error) => {
                commit(UPDATE_LOADING, false);
                reject(error);
            })
    })
},

구성 요소Question다음과 같은 방법을 가지고 있다.skip, 그리고 그것은 "라고 부른다.vuex액션skipQuestion그리고 배출되어야 한다.skip상위 구성 요소에 대한 이벤트.

...mapActions(['skipQuestion']),
skip(evt) {
    let payload = { id: this.question_id };
    this.skipQuestion(payload).then( () => {
        this.$emit('skip', this.uuid);
    }).catch( (error) => {
        console.log(error);
    });
},

문제는, 그 다음이skip이벤트 사용 시 상위 항목에 이벤트가 전달되지 않음then행동의 차단Chrome용 Vue 개발자 콘솔도 다음을 확인하십시오.skip사건이 터졌다.내가 배출구를 블록 밖에 두면 모든 것이 작동한다.뭐가 잘못됐는지 제안할 거 있어?

편집 1

다음 코드도 시도해보고 두 로그 문장이 모두 콘솔에 인쇄된다.

skip(evt) {
    let payload = { id: this.question_id };
    let vm = this; 
    this.skipQuestion(payload).then( () => {
        console.log('before skip emit');
        vm.$emit('skip', this.uuid);
        console.log('after skip emit');
    }).catch( (error) => {
        console.log(error);
    });
},

편집 2

다음은 하위 이벤트를 청취하는 데 사용되는 템플릿 코드:

<question v-bind="question"
          :key="question.uuid"
          v-if="questionReady"
          v-on:skip="onSkipQuestion"
          v-on:answer="onAnswerQuestion">
</question>

앞에서 말한 바와 같이, 본사가 반환한 약속/그 후 블록을 사용하지 않는 경우axios부탁이야, 방출은 효과가 있어아래에는 다음과 같은 방법을 찾을 수 있다.

methods: {
  onSkipQuestion(payload) {
    // this code is not executed
    console.log('onSkipQuestion')

    //....
  },


  //....
}      

제공된 정보를 요약하십시오.

크롬용 vue 개발자 콘솔도 스킵 이벤트가 발생했음을 확인한다.


TL;DR

  • vm.$emit 에 열거된 모든 방법을 기본적으로 호출하다.vm._events[eventName]

  • v-on을 통해 등록됨context.listeners을 통해 주입된.


기본적으로 다음을 사용하여 디버그할 수 있음debugger문:

skip(evt) {
    let payload = { id: this.question_id };
    this.skipQuestion(payload).then( () => {
        debugger; // scope -> _events & scope -> $parent.componentInstance
        // or console.log(JSON.stringify(this._events))
        this.$emit('skip', this.uuid);
    }).catch( (error) => {
        console.log(error);
    });
},

그럼 무슨 일이 일어나고 있는지 알겠지.


확인할 사항:

  • 유효의this범위

  • 유효의parent

  • 해결된 것으로 실제로 트리거됨

  • vm._events등록한

에 대한 참조를 분실하셨습니다.this그 블록 안에.이제 참조는 콜백 함수가 호출된다.대신 이렇게 해라.

 ...mapActions(['skipQuestion']),
    skip(evt) {
        let payload = { id: this.question_id };
        let vm = this; // Preserve Vue instance for use inside block
        this.skipQuestion(payload).then( () => {
            vm.$emit('skip', vm.uuid);
        }).catch( (error) => {
            console.log(error);
        });
    },

아마도 문제는 당신이 스킵질문()에서 해결()이나 거부()를 반환하지 않는 것일 것이다.

어쨌든, 당신의 어플리케이션이 ES2017 (또는 그 이상)을 사용한다고 가정하거나, 만약 그렇지 않다면, 나는 그 기능을 사용할 수 있도록 세분화 할 것이다.async / await하도록 구조화하다this어떤 위험(Varun의 대답 참조)도 없을 것이며, 어떤 위험도 없을 것이다.skipQuestion()현재와 같은 어떤 것도 반환하지 않음:

async skip(evt) {
    let payload = { id: this.question_id };
    try {
      let result = await skipQuestion(payload)
      this.$emit('skip', this.uuid);
    } catch(error){
      console.log(error);
    }
}

돌아오지 않음resolve / reject...의 경우에 버그 발생원으로 알려져 있다.Promise((resolve, reject) => {...})구문

나는 정확히 똑같은 문제를 가지고 있었고 무슨 일이 일어나고 있는지 아무리 생각해도 알 수가 없었다.내가 생각할 수 있는 것은 그 구성 요소가 어떻게 해서든 약속의 해결을 기다리는 동안 사건을 발산하는 능력을 상실하고 있다는 것이다.

어쨌든 나의 해결책은 약속 그 자체를 내보내는 것이었다, 이렇게.

skip(evt) {
    let payload = { id: this.question_id };
    this.$emit('skip', skipQuestion(payload));
}

그리고 부모님의 경우, 할 수 있다.

... @skip="receive_skip($event)" ...

...

methods: {
    receive_skip(skipped) {
        skipped
        .then((data) => {
            // do something on success
        })
        .catch((err) => {
            // do something on fail
        });
    }
}

깔끔하고 우아하지는 않지만, 일을 완성시켜 준다.

참조URL: https://stackoverflow.com/questions/58449712/vue-js-component-does-not-emit-to-parent-after-successful-axios-call

반응형