繁体   English   中英

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

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

我有一个从我的服务器获取一些数据的子组件,在获取之前我将加载状态更改为 true,并且我想在获取完成后将其设置为 false。 所以我在我的子组件中做了类似的事情:

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

在我的父组件中,我像这样听这个事件:

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

最后在updateLoadingStatus中,我将isLoading值相应地设置为truefalse

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

这对于显示或不显示我的loading组件很有用:

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

我的问题是第一个发射正在工作并且isLoading值设置为true但第二个不工作并且我的isLoading值永远保持为true ......在我的方法updateLoadingStatus我记录了status值,我看到了这个方法只调用一次。

我通过在模板中使用v-show而不是v-if解决了这个问题。

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

我知道这是一个老问题,但我今天偶然发现了类似的情况,终于明白了为什么该机制与v-show一起工作,而不是v-if

如果你得到以下<template>标签:

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

以及以下<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
        },
    },
}

看起来不错,对吧? 您可以从<component-b>捕获set-loading-status事件并将其设置为true 但是您无法再次捕获它以将其设置回false

但是,让我们看一下 关于v-ifv-show的官方 Vue 文档

v-if 是“真正的”条件渲染,因为它确保条件块内的事件侦听器和子组件在切换期间被正确销毁和重新创建。

现在您可以看到当isLoading设置为truecomponent-b被销毁,并且您将无法捕获发出的事件以将其更改回false

因此,在这种特殊情况下,您必须使用v-show来处理加载状态。

暂无
暂无

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

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