在 Vue 中对对象使用 $emit 时无法更改数据值



使用$emitchild与组件之间进行通信parent。我在子组件中有一个方法,可以在api调用的不同阶段触发$emit。即,在进行 api 调用之前,我需要向父级发送一些值以禁用父级中的某些字段。因此,使用$emit发送这些值并且可以成功运行。但是当我在以相同的方法从 api 获取结果后尝试调用相同的$emit事件时,它没有得到更新。这些值已成功从子级发出,但在父级中,它仅在第一次更新。

这是父组件

<template>
<div>
<div class="horizontal-fields">
<input
id="General_mobile"
class="input-fied"
name="mobileNumber"
placeholder="Enter your mobile"
type="number"
autocomplete="new mobile"
:disabled="otpInput.isVerifying"
>
<input @click.prevent="sendVerificationCode" value="sendotp" class="otp-btn" type="button">
</div>
<div v-if="otpInput.isOtpMode">
<GeneralOtp
:message="otpGeneratedMessage"
:mobileNumber="this.mobileNumber"
@handleComplete="handleCompleteOtp"
/>
</div>
</div>
</template>
<script>
import axios from "axios";
import GeneralOtp from "./GeneralOtp";
export default {
name: "MobileVerification",
components: {
GeneralOtp
},
data() {
return {
mobileNumber: null,
isValidMobile: null,
buttonValue: "Send OTP",
otpGeneratedMessage: null,
otpInput: {
isOtpMode: false,
isVerifying: false,
otpToken: null,
currentVerifiedMobile: null
}
};
},
methods: {
async sendVerificationCode() {
const { data } = await axios.get(
"https://jsonplaceholder.typicode.com/todos/1"
);
if (data.userId) {
this.otpGeneratedMessage = "some message from server";
this.otpInput.isOtpMode = true; //to show otp input field(child component)
}
},
handleCompleteOtp(value) {
console.log("called");
this.otpInput = value;
}
}
};
</script>

这是子组件

<template>
<div>
<div v-if="!isVerifying">
<input id="otp" class="input-fied" name="otpcode" placeholder="Enter your otp" type="number">
<input @click.prevent="this.verifyOtp" value="buttonValue" class="otp-btn" type="button">
<p style="margin-top: 2%">{{ message }}</p>
</div>
<div v-else="isVerifying">
<p>Please wait</p>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
props: {
message: {
type: String,
default: ""
},
mobileNumber: {
type: String,
default: null
}
},
data() {
return {
isVerifying: false
};
},
methods: {
async verifyOtp() {
/* Disable inputs & show loading */
this.isVerifying = true;
this.respondToParent({
otpToken: null,
mobileNumber: this.mobileNumber,
isVerifying: this.isVerifying,
isOtpMode: false
});
/* Send verify request to server */
const { data } = await axios.get(
"https://jsonplaceholder.typicode.com/todos/1"
);
/* If success & valid hide in parent send verified flag to parent */
/* If success & invalid otp show error */
this.isVerifying = false;
if (data.userId) {
this.respondToParent({
otpToken: "token from a success response",
mobileNumber: this.mobileNumber,
isVerifying: false,
isOtpMode: false
});
} else {
this.respondToParent({
OtpToken: null,
mobileNumber: this.mobileNumber,
isVerifying: this.isVerifying,
isOtpMode: false
});
}
/* If error show retry button with error message */
},
respondToParent(value) {
this.$emit("handleComplete", {
otpToken: value.otpToken,
mobileNumber: this.mobileNumber,
isVerifying: value.isVerifying,
isOtpMode: value.isOtpMode
});
}
}
};
</script>

我不知道为什么它第二次没有更新,即使它两次都被从孩子调用。以某种方式设法在沙盒环境中复制相同的内容。 代码沙箱中的代码

第一次调用this.respondToParent时,它将otpInput.isOtpMode设置为 false,因此不会呈现GeneralOtp,因为您使用的是 v-if:

<div v-if="otpInput.isOtpMode">
<GeneralOtp
:message="otpGeneratedMessage"
:mobileNumber="this.mobileNumber"
@handleComplete="handleCompleteOtp"
/>
</div>

如果您将第一个this.respondToParent更改为

this.respondToParent({
otpToken: null,
mobileNumber: this.mobileNumber,
isVerifying: this.isVerifying,
isOtpMode: true
});

(请注意,isOtpMode: true(

我认为您应该在第一次调用中保持isOtpMode是正确的,并按照您所说使用isVerifying禁用父组件中的某些内容。

在这里演示

最新更新