[英]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
值相应地设置为true
或false
。
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-if
和v-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
设置为true
时component-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.