【问题标题】:Vuetify v-dialog is mounted multiple times after use and is not within a loopVuetify v-dialog 使用后挂载多次且不在循环内
【发布时间】:2021-01-17 06:53:56
【问题描述】:

我有两个对话框;登录注册。该对话框使用: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.

我做了什么

  • 在两个对话框中添加 :retain-focus="false"。它消除了错误,但 对话框仍被多次挂载
  • v-if="!this.user" 替换为 v-show="!this.user";仍在多次安装
  • 在关闭对话框之前使用 setTimeout,然后使用 router.push
  • 每次用户注销时重新加载页面。虽然这工作,但我需要经常刷新 每次使用 Dialog 时

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 (PopupSignIn)

<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 组件流程大致相同,唯一的区别是用于注册。

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

【问题讨论】:

    标签: javascript vuejs2 modal-dialog vuetify.js vuex


    【解决方案1】:

    我尝试了一种不同的方法来使用 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>
    

    登录.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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-22
      • 2019-12-28
      • 2021-11-22
      • 1970-01-01
      • 1970-01-01
      • 2019-07-31
      • 2020-10-29
      • 2019-04-24
      相关资源
      最近更新 更多