невозможно изменить значения данных при использовании $emit для объекта в vue

невозможно изменить значения данных при использовании $emit для объекта в vue

26.12.2019 03:15:24 Просмотров 54 Источник

Использование $emitдля связи между childparentкомпонентами. У меня есть метод в дочернем компоненте, который запускает $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

У вопроса есть решение - Посмотреть?

https://stackoverflow.com/questions/59482734/unable-to-change-data-values-when-using-emit-on-an-object-in-vue#comment105141877_59482734
@AdamOrlov код все еще не работает. Я не знаю, почему codesandbox не работает. Никогда раньше этим не пользовался. Изменения не повторяются в предварительном просмотре codesandbox. прости меня за это.
https://stackoverflow.com/questions/59482734/unable-to-change-data-values-when-using-emit-on-an-object-in-vue#comment105142140_59482734
@AdamOrlov codesandbox теперь работает, и демо-версия точно работает по веб-адресу 20unr.sse.codesandbox.io
https://stackoverflow.com/questions/59482734/unable-to-change-data-values-when-using-emit-on-an-object-in-vue#comment105142285_59482734
@LawrenceCherone нет. даже при том, что его правильно получить испускается родительское состояние не меняется при втором вызове $emit

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

Является ответом!
ittus

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)

Я думаю, что вы должны сохранить isOtpModeis true в первом вызове и использовать isVerifyingчтобы отключить что-то в Родительском компоненте, как вы сказали.

Демо здесь

https://stackoverflow.com/questions/59482734/unable-to-change-data-values-when-using-emit-on-an-object-in-vue/59483074#comment105142340_59483074
Это заняло у меня 2 дня. Я думал что-то связано с состояние каждый раз, как я обновление объекта в родителе. Большое спасибо, приятель.
Закрыть X