Vuetify v-dialog 在使用后多次挂载,不在循环内

Vuetify v-dialog is mounted multiple times after use and is not within a loop

我有两个对话框;登录注册。该对话框使用 :value="dialog" 而不是 v-model:dialog 因为它 dialog 是计算数据。 dialog 取自 vuex 模块(弹出窗口)。对话框是在没有激活器的情况下完成的(由 Vuetify 提供)。

如果在 PopupSignIn 组件中单击“注册”按钮,它将自行关闭并通过调用 togglePopupAccountSignInSignUp 打开 PopupSignUp,反之亦然。 对话框可以很好地切换 但是 ONCE 我填写一个表格来登录或注册并执行操作。它让我登录,Vue 给出了一个错误(第一个)。然后在注销并再次打开“登录”对话框时出现另一个(第二个)错误。

错误

第一个错误

vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in nextTick: "TypeError: Cannot read property 'focus' of undefined"

found in

---> <VDialog>
       <PopupSignIn> at src/components/popup/SignIn.vue
         <VApp>
           <App> at src/App.vue
             <Root>

第二个错误

Uncaught RangeError: Maximum call stack size exceeded.

我做了什么


location.reload();
return false;

App.vue

<!-- There is no loop going on within the header tag -->
<header>
...
<PopupSignIn v-if="!this.user" />
<PopupSignUp v-if="!this.user" />
...
</header>

popup.js

export const namespaced = true;

export const state = {
  account: {
    signIn: false,
    signUp: false
  }
};

export const mutations = {
  SET_POPUP_ACCOUNT_SIGN_IN(state, bool) {
    state.account.signIn = bool;
  },
  SET_POPUP_ACCOUNT_SIGN_UP(state, bool) {
    state.account.signUp = bool;
  }
};

export const actions = {
  updatePopupAccountSignIn({ commit }, bool) {
    commit("SET_POPUP_ACCOUNT_SIGN_IN", bool);
  },
  updatePopupAccountSignUp({ commit }, bool) {
    commit("SET_POPUP_ACCOUNT_SIGN_UP", bool);
  },
  togglePopupAccountSignInSignUp({ commit, state }) {
    commit("SET_POPUP_ACCOUNT_SIGN_IN", !state.account.signIn);
    commit("SET_POPUP_ACCOUNT_SIGN_UP", !state.account.signIn);
  }
};

SignIn.vue(弹出登录)

<template>
  <div>
    <v-btn @click.stop="updatePopupAccountSignIn(true)">
      <v-icon>
        mdi-account
      </v-icon>
      Sign In
    </v-btn>

    <v-dialog
      :value="dialog"
      :retain-focus="false"
      @click:outside="updatePopupAccountSignIn(false)"
    >
      <v-card>
        <v-card-title>
          <div>Sign In</div>
        </v-card-title>

        <v-card-text>
          <v-form
            ref="form"
            v-model="valid"
            lazy-validation
            @submit.prevent="login"
          >

          <!-- Rest of the form -->

            <v-btn
              type="submit"
              :loading="loading"
              :disabled="loading"
              >Sign In</v-btn
            >
          </v-form>

          <div>
            <p>Don't have an account?</p>
            <v-btn
              @click.stop="togglePopupAccountSignInSignUp"
              >Sign Up</v-btn
            >
          </div>
        </v-card-text>
      </v-card>
    </v-dialog>
  </div>
</template>

<script>
export default {
  computed: {
    ...mapState("popup", {
      dialog: state => state.account.signIn
    })
  },
  methods: {
    ...mapActions("account", ["signIn"]),
    ...mapActions("popup", [
      "updatePopupAccountSignIn",
      "updatePopupAccountSignUp",
      "togglePopupAccountSignInSignUp"
    ]),
    async login() {
      try {
        this.loading = true;

        await this.signIn({
          email: this.email,
          password: this.password.value
        });

        ...

        setTimeout(() => {
          this.updatePopupAccountSignIn(false);
          this.updatePopupAccountSignUp(false);

          this.$router.push("/your/profile");
        }, 2000);
      } catch (error) {
        ...
      }
    }
  }
};
</script>

SignUp组件流程与SignIn组件流程大致相同,唯一不同的是它用于注册。

我不确定是什么导致对话框被多次安装。非常感谢任何解决此问题的帮助。

我尝试了一种不同的方法来使用 Vue .sync 修饰符并删除 vuex 方法来获得预期结果。更多内容可阅读 Jithil Jishad's blog.

App.vue

<template>
  <header>
  ...
  <PopupSignIn
    v-if="!user"
    :dialog.sync="dialog.signIn"
    :dialogSignUp.sync="dialog.signUp"
  />
  <PopupSignUp
    v-if="!user"
    :dialog.sync="dialog.signUp"
    :dialogSignIn.sync="dialog.signIn"
  />
  ...
  </header>
</template>

<script>
export default {
  ...
  data() {
    return {
      dialog: {
        signIn: false,
        signUp: false
      }
    };
  },
  ...
};
</script>

SignIn.vue

<template>
  <v-dialog
    v-model="dialog"
    @click:outside.stop="$emit('update:dialog', false)"
  >
    <v-card>
      <v-card-text>
        <!-- FORM -->
        <p>Don't have an account?</p>
        <v-btn @click.stop="toggleDialog">Sign Up</v-btn>
      </v-card-text>
    </v-card>
  </v-dialog>
</template>

<script>
export default {
  props: {
    dialog: Boolean,
    dialogSignUp: Boolean
  },
  beforeDestroy() {
    this.$emit("update:dialog", false);
  },
  methods: {
    toggleDialog() {
      this.$emit("update:dialog", false);
      this.$emit("update:dialogSignUp", true);
    }
  }
};
</script>