简体   繁体   English

Vue.js 从未捕获的子组件发出事件

[英]Vue.js emit event from child component not catched

I have a child component which fetch some data from my server, before fetching I change the loading status to true and I want to set it to false after the fetch is completed.我有一个从我的服务器获取一些数据的子组件,在获取之前我将加载状态更改为 true,并且我想在获取完成后将其设置为 false。 So I do something like that in my child component:所以我在我的子组件中做了类似的事情:

mounted() {
    this.$emit('update:loadingMessage', 'Loading version options from Artifactory...');
    this.$emit('update:isLoading', true);
    this.fetchVersions();
},

methods: {
    fetchVersions() {
        const promises = [
            this.$http.get(`${process.env.API_URL}/version/front`),
            this.$http.get(`${process.env.API_URL}/version/back`),
        ];
        Promise.all(promises)
            .then((values) => {
                // Do some stuff
            })
            .then(() => {
                this.$emit('update:isLoading', false);
            })
            .catch(requestService.handleError.bind(this));
    },
},

And in my parent component I listen to this event like that:在我的父组件中,我像这样听这个事件:

<version-selector
    :form="form"
    @update:loadingMessage="updateLoadingMessage"
    @update:isLoading="updateLoadingStatus"
    :isSnapshotVersion="isSnapshotVersion">
</version-selector>

Finally in the updateLoadingStatus I set the isLoading value to true or false accordingly.最后在updateLoadingStatus中,我将isLoading值相应地设置为truefalse

updateLoadingMessage(message) {
  this.$log.debug(message);
  this.loadingMessage = message;
},
updateLoadingStatus(status) {
  this.$log.debug(status);
  this.isLoading = status;
},

This is useful to display or not my loading component:这对于显示或不显示我的loading组件很有用:

<loading
    v-if="isLoading"
    :loadingMessage="loadingMessage"
    :isGiphy="true">
</loading>

My problem is that the first emit is working and the isLoading value is set to true but the second one is not working and my isLoading value stay to true forever... In my method updateLoadingStatus I log the status value and I see that this method is just called once.我的问题是第一个发射正在工作并且isLoading值设置为true但第二个不工作并且我的isLoading值永远保持为true ......在我的方法updateLoadingStatus我记录了status值,我看到了这个方法只调用一次。

I solved the problem by using v-show instead of v-if in my template.我通过在模板中使用v-show而不是v-if解决了这个问题。

<loading
  v-show="isLoading"
  :loadingMessage="loadingMessage"
  :isGiphy="true">
</loading>

I know this is an old question, but I stumbled into a similar situation today, and finally understood why the mechanism was working with v-show , and not v-if .我知道这是一个老问题,但我今天偶然发现了类似的情况,终于明白了为什么该机制与v-show一起工作,而不是v-if

If you get the following <template> tag:如果你得到以下<template>标签:

<div>
    <component-a v-if="isLoading" />
    <component-b v-else @set-loading-status="setIsLoading" />
</div>

And the following <script> tag:以及以下<script>标签:

import ComponentA from './ComponentA'
import ComponentB from './ComponentB'
export default {
    name: 'ParentComponent',
    components: { ComponentA, ComponentB },
    data() {
        return {
            isLoading: false,
        }
    },
    methods: {
        setIsLoading(isLoading) {
            this.isLoading = isLoading
        },
    },
}

It seems fine, right?看起来不错,对吧? You can catch the set-loading-status event from the <component-b> and set it to true .您可以从<component-b>捕获set-loading-status事件并将其设置为true But you can't catch it again to set it back to false .但是您无法再次捕获它以将其设置回false

But, let's take a look in the official Vue docs about v-if and v-show :但是,让我们看一下 关于v-ifv-show的官方 Vue 文档

v-if is “real” conditional rendering because it ensures that event listeners and child components inside the conditional block are properly destroyed and re-created during toggles. v-if 是“真正的”条件渲染,因为它确保条件块内的事件侦听器和子组件在切换期间被正确销毁和重新创建。

Now you can see that the component-b gets destroyed when isLoading is set to true , and you won't be able to catch the emitted event to change it back to false .现在您可以看到当isLoading设置为truecomponent-b被销毁,并且您将无法捕获发出的事件以将其更改回false

So, in this particular case, you must use v-show to handle the loading status.因此,在这种特殊情况下,您必须使用v-show来处理加载状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM