javascript - Vuex 观察者错误地触发了两次
问题描述
我现在已经搜索了 2 个小时,我对自己做错了什么一无所知.. 希望有人可以帮助我:
基本上这很容易。我有一个可重用的 Recaptchas 组件。有问题的元素是“忘记密码”弹出对话框中的文本字段(在登录掩码上)
处理不同验证码的基本思想(因为同一页面上有两个)是:
- 我为每个可能的验证码都有一个 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 中的观察者注意到并开始评估(这个错误触发了两次)
- 如果经过验证,
verifyCaptcha()
在 recaptcha.vue 存储到 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
},
突变.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
不会对另一个组件产生任何影响。
推荐阅读
- python - 如何更改 matplotlib 工具栏的平移和缩放按钮的模式
- php - Laravel 同时使用 2 个 api 级别,彼此分开
- c++ - 在 Eclipse 编辑器中为单个文件强制执行特定的语法突出显示
- r - 在 R 中使用 100 多个特征 lm 函数
- driver - Linux 函数 i2c ds1307_probe 未调用
- image-processing - 使用python自己实现二进制阈值但得到错误的结果
- android - 无法从图库中选择图像
- python - 有没有办法在 Python 3.6 中将列表输入到以 *args 作为其参数的函数中?
- flutter - 如何更改颤振 showAboutDialog 中的文本按钮颜色?
- r - 为什么在使用 `tidyverse` 包中的 `pivot_wider()` 时会出现错误?