You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3中按钮加载Spinner无法停止问题求助(附代码)

解决Vue组件中grecaptcha回调里无法修改loading状态的问题

问题原因

你遇到的错误是因为回调函数的this指向不对:grecaptcha.ready()和grecaptcha.execute()里用的是普通function,这类函数会改变this的指向,不再指向Vue组件实例。即使onSuccess用了箭头函数,它继承的是外层普通函数的this(浏览器环境下是window),自然无法访问组件的loading属性。

解决方案

有两种简单的修复方式:

方案1:提前保存Vue实例引用

在recaptcha方法开头把组件实例的this存到一个变量里,后续所有需要访问组件数据的地方都用这个变量代替this:

export default {
    name: 'form-loading-spinner',
    data(){  
        return{
            loading: false,
            form : {
                phone: "",
                token: null,
            },
        }
    },
    methods:{
            recaptcha(){
                const vm = this; // 保存组件实例引用
                vm.loading = true;                
                let form = vm.form;               
                    grecaptcha.ready(function() {                                  
                        grecaptcha.execute('XXXXXXXXXXXXXXXXXX', {action: 'submit'}).then(function(token) {                                     
                            form.token =  token;
                            Inertia.post("/phone/send", form, {
                                preserveScroll: true, 
                                onSuccess: () => vm.loading = false // 用vm访问loading
                            })
                            });                        
                        }) 
            },
            reset(){
                this.loading =  false;
            },
    }
}

方案2:把所有回调改成箭头函数

箭头函数不会改变this指向,会继承外层作用域的this(也就是Vue组件实例),所以把grecaptcha.ready()和grecaptcha.execute()里的回调都换成箭头函数即可:

export default {
    name: 'form-loading-spinner',
    data(){  
        return{
            loading: false,
            form : {
                phone: "",
                token: null,
            },
        }
    },
    methods:{
            recaptcha(){
                this.loading = true;                
                let form = this.form;               
                    grecaptcha.ready(() => { // 改成箭头函数
                        grecaptcha.execute('XXXXXXXXXXXXXXXXXX', {action: 'submit'}).then((token) => { // 改成箭头函数
                            form.token =  token;
                            Inertia.post("/phone/send", form, {
                                preserveScroll: true, 
                                onSuccess: () => this.loading = false
                            })
                            });                        
                        }) 
            },
            reset(){
                this.loading =  false;
            },
    }
}

额外提示

注意你按钮上的:disabled="form.processing",如果form.processing不是组件数据里的属性,建议改成:disabled="loading",让按钮禁用状态和Spinner的显示状态保持一致,避免出现状态不同步的问题。

内容的提问来源于stack exchange,提问作者Марк Мина

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 11:42:55