VueJS中Facebook登录按钮首次点击报错仅第二次点击生效问题
问题根因
- 你写的
loadFacebookSDK、initFacebook方法虽然声明了async,但内部没有返回Promise,await不会等待SDK加载、FB初始化完成就直接执行后续的window.FB.login,首次点击时Facebook SDK还没加载完成,window.FB为undefined所以报错。第二次点击时SDK已经加载完成,所以可以正常运行。 - FB回调里用普通函数声明,
this指向会偏移,后续设置this.progress会失效。
修复后的代码
修改methods部分
methods: { // 改造initFacebook,返回Promise等待FB初始化完成 initFacebook() { return new Promise(resolve => { window.fbAsyncInit = function() { window.FB.init({ appId: "615100826501510", // 替换为自己的appId cookie: true, version: "v2.6" }); resolve(window.FB) // 初始化完成后resolve }; }) }, async logInWithFacebook() { this.progress = true // 先判断FB是否已经加载初始化过,避免重复加载 if (!window.FB) { await this.loadFacebookSDK(document, "script", "facebook-jssdk"); await this.initFacebook(); } // 回调改用箭头函数,修正this指向 window.FB.login((response) => { if (response.status === 'connected'){ window.FB.api('/me?fields=id,name,email', (response) => { console.log(response) this.progress = false }) } else { alert("用户取消了登录或未完成授权。"); this.progress = false } }, {scope: 'public_profile,email'} ); return false; }, // 改造loadFacebookSDK,返回Promise等待SDK加载完成 loadFacebookSDK(d, s, id) { return new Promise((resolve, reject) => { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) { resolve() return; } js = d.createElement(s); js.id = id; js.src = "https://connect.facebook.net/en_US/sdk.js"; // 加载完成后resolve js.onload = resolve js.onerror = reject fjs.parentNode.insertBefore(js, fjs); }) } }
可选优化
如果不想等用户点击才加载SDK,可以把SDK加载和初始化逻辑放到mounted生命周期里执行,用户点击按钮时可以直接调用登录,体验更流畅:
mounted() { // 组件加载完成就提前初始化FB SDK this.loadFacebookSDK(document, "script", "facebook-jssdk") .then(() => this.initFacebook()) },
内容的提问来源于stack exchange,提问作者user16643863
相关产品推荐
相关产品推荐

