невозможно изменить значения данных при использовании $emit для объекта в vue
Использование $emit
для связи между child
parent
компонентами. У меня есть метод в дочернем компоненте, который запускает $emit во время различных этапов вызова api
. т. е. перед вызовом api мне нужно отправить несколько значений в parent, чтобы отключить некоторые поля в parent. Таким образом, используя $emit
для отправки этих значений, и это работает успешно. Но затем, когда я пытаюсь вызвать то же самое событие $emit после получения результата от api в том же методе, он не обновляется. Значения успешно передаются из дочернего элемента, но в Родительском он обновляется только в первый раз.
Вот родительский компонент
<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>
Я не могу понять, почему он не обновляется во второй раз, хотя его называют оба раза от ребенка. Каким-то образом удалось воспроизвести то же самое в среде песочницы. код в codesandbox





Ответы - невозможно изменить значения данных при использовании $emit для объекта в vue / unable to change data values when using $emit on an object in vue

26.12.2019 04:37:06
В первый раз, когда ты позвонила this.respondToParent
, он устанавливает otpInput.isOtpMode
в false, поэтому GeneralOtp
не будет отображаться, потому что вы используете v-if:
<div v-if="otpInput.isOtpMode">
<GeneralOtp
:message="otpGeneratedMessage"
:mobileNumber="this.mobileNumber"
@handleComplete="handleCompleteOtp"
/>
</div>
Вы можете проверить, что он будет вызван 2 раза, если вы измените свой первый this.respondToParent
в
this.respondToParent({
otpToken: null,
mobileNumber: this.mobileNumber,
isVerifying: this.isVerifying,
isOtpMode: true
});
(Обратите внимание, что isOtpMode: true
)
Я думаю, что вы должны сохранить isOtpMode
is true в первом вызове и использовать isVerifying
чтобы отключить что-то в Родительском компоненте, как вы сказали.
Демо здесь
