javascript - Vuex 观察者错误地触发了两次

标签 javascript vue.js vuejs2 components vuex

我已经搜索了 2 个小时了,我零知道我做错了什么..希望有人可以帮助我:

基本上这很容易。我有一个可重复使用的验证码组件。 有问题的元素是弹出对话框中“忘记密码”的文本字段(通过登录掩码)

处理不同验证码的基本思想(因为同一页面上有两个)是:

  • 我为每个可能的验证码都有一个 vuex 字段,初始化为 null
  • 对于每个表单提交按钮,我都会触发一个突变,将验证码字段设置为 0
  • 然后我在 recaptcha 组件中设置了监听器来监听更改,并且 if === 0,开始评估验证码
  • 然后onValidated,调用一个突变将结果保存到vuex。然后另一个使用 if(newVal) 的观察者提交整个内容。

根据我的理论,这没有问题。我记得它在过去的某个时候已经起作用了(或者我只是没有注意到双重提交),但现在我做了一些更改,它的行为真的很奇怪。

准确地说:我单击按钮一次,一切正常,但是一个观察者触发了两次,即使它根本不应该。 之前的所有内容都会触发一次,只有那个观察者会触发两次,即使我这样做了

if (!this.running) {
            this.running = true
            console.log('forgot watcher 2')
            this.$refs.recaptcha.execute()
        }

但它也不起作用。它似乎在同一时间运行它们,这对我来说没有意义

控制台输出是这样的:

submit
verify forgot captcha
0
forgot watcher 2
0
forgot watcher 2
verified
forgot captcha verified 03AOLTBLTP...............
forgot watcher
verified
forgot watcher

所以以一种易于理解的方式:

  • 点击login.vue
  • 突变将值设置为 0
  • recaptcha.vue 中的观察者注意到并开始评估(这个错误地触发了两次)
  • 如果经过验证,recaptcha.vue 中的 verifyCaptcha() 会存储到 vuex

我的文件如下:

登录.vue

<template>
  <v-form
    @submit.prevent="twoFaRequired ? sendTwoFa() : verifyLoginCaptcha()"
  >
    // ...
   <recaptcha />
    // ...
    <v-layout>
        <form>
           // ...
           <recaptcha />
           <v-btn
              color="primary"
              :loading="forgotLoading"
              :disabled="successful || forgotLoading || $v.$invalid"
              @click.native.stop.prevent="verifyForgotCaptcha"
            >Reset Password</v-btn>

//...
  methods: {
    verifyForgotCaptcha() {
      console.log('submit')
      this.$store.commit('user/VERIFY_FORGOT_CAPTCHA')
    },
//...
  watch: {
    forgotCaptcha(newVal, oldVal) {
      if (newVal) {
        console.log('forgot watcher')
        this.sendForgotEmail()
      }
    },
//...
    forgotCaptcha() {
      return this.$store.state.user.forgotCaptcha
    },

mutations.js

//...
  VERIFY_FORGOT_CAPTCHA(state) {
    console.log('verify forgot captcha')
    state.forgotCaptcha = 0
  },
  FORGOT_CAPTCHA_VERIFIED(state, payload) {
    console.log('forgot captcha verified', payload)
    state.forgotCaptcha = payload
  },
//...

recaptcha.vue

<template>
  <div class="d-flex justify-center">
    <vue-recaptcha
      ref="recaptcha"
      :sitekey=siteKey
      :loadRecaptchaScript="true"
      size="invisible"
      @verify="verifyCaptcha">
    </vue-recaptcha>
  </div>
</template>

<script>
  import VueRecaptcha from 'vue-recaptcha'
  import { mapGetters } from 'vuex'

  export default {
    data: () => ({
      running: false,
      usage: '',
      siteKey: 'xxxxxxx'
    }),
    components: { VueRecaptcha },
    computed: {
      ...mapGetters([
        'user'
      ]),
    //...
      isForgotCaptcha() {
        return this.$store.getters['user/forgotCaptcha']
      }
    },
    methods: {
      verifyCaptcha(response) {
        console.log('verified')
    //...
          if (this.usage === 'forgot')        this.$store.commit('user/FORGOT_CAPTCHA_VERIFIED', response)
        this.usage = ''
        this.$refs.recaptcha.reset()
      }
    },
    watch: {
    //...
      isForgotCaptcha(newVal) {
        if (newVal === 0) {
          console.log('forgot watcher 2')
          this.usage = 'forgot'
          this.$refs.recaptcha.execute()
        }
      },
    }
  };
</script>

如果您需要更多信息/代码,请随时询问。我希望任何人都可以告诉我我做错了什么。我要疯了。 谢谢!

最佳答案

login.vue您有 <recaptcha> 的两个实例。其中每个都有自己的一组观察者,它们不是共享的。同样,他们每个人都有自己的计算属性 isForgotCaptcha .

何时 user/forgotCaptcha改变它会改变 isForgotCaptcha两个组件的属性,触发它们的每个观察者。

设置this.running只会为 recaptcha 之一设置该属性组件,不会对其他组件产生任何影响。

关于javascript - Vuex 观察者错误地触发了两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58549830/

相关文章:

javascript - 通过字符串路径设置嵌套对象属性

javascript - 在页面上加载所有 iframe 的全部内容后不显示警报

javascript - 运行函数直到变量达到特定值

javascript - 将日期传递给 Date 对象会导致 IE8 中的变量未定义

vue.js - beforeRouteUpdate 和 watching '$route' - Vue.js 之间的区别?

vue.js - 如何在不注入(inject)的情况下创建全局组件?

javascript - 如何使用下拉选择填充文本字段

javascript - Laravel - 如何将 Vue 组件导入到另一个组件

vue.js - vue js,如何在模板中传递数组?

vue.js - v-on :change does not work for vue-multiselect