【发布时间】:2018-07-19 12:08:14
【问题描述】:
我想在 Vue.js 组件安装后渲染 recaptcha。它适用于正常加载和重新加载,但是当我导航到另一个 url 并单击浏览器后退按钮时,它会引发错误。
这是我的设置:
-
我正在页面底部加载
api脚本:<script src='https://www.google.com/recaptcha/api.js' async></script> -
在该页面上,我呈现了一个名为
Contact.vue的全局注册组件,其中包含一个名为Recaptcha.vue的本地组件:<app-recaptcha @recaptchaResponse="updateRecaptchaResponse"></app-recaptcha>
Recaptcha.vue 的代码如下所示:
<template>
<div id="app-recaptcha">
<div :id="placeholderId"></div>
</div>
</template>
<script>
export default {
data() {
return {
sitekey: 'key_here',
placeholderId: 'grecaptcha',
widgetId: null
}
},
mounted() {
this.$nextTick(function () {
this.render();
});
},
methods: {
render() {
this.widgetId = window.grecaptcha.render(this.placeholderId, {
sitekey: this.sitekey,
callback: (response) => {
this.$emit('recaptchaResponse', response);
}
});
},
reset() {
window.grecaptcha.reset(this.widgetId);
}
}
}
</script>
<style>...</style>
在正常页面加载/重新加载this.render() 正常执行。但是,当我导航到另一个 url 并通过返回按钮返回时,我得到:Error in nextTick: "TypeError: window.grecaptcha.render is not a function"。
我尝试过:
-
在
api脚本的onload事件上设置一个变量:<script src='...' onload="window.script = { recaptcha: 'ready' }" async></script> -
然后将其作为属性添加到
Recaptcha.vue的data()中:ready: window.script.recaptcha 接下来,我在
ready属性上添加了一个观察者,并在该观察者中尝试运行this.render()
没有成功,错误依然存在。我认为即使在正常的加载/重新加载情况下,我也只是“幸运”了 api 脚本在组件安装之前加载,并且将 this.render() 放在 mounted() 钩子内没有帮助。
您知道如何向Recaptcha.vue 发出外部脚本已完成加载的信号,然后才渲染recaptcha?
【问题讨论】:
-
通常只使用
async或defer,不能同时使用。 -
已更正,谢谢。
-
感谢您的建议,但这并不能真正回答我的问题。我更喜欢一种更简单的方法来指示脚本已加载的组件。
标签: javascript vue.js vuejs2 dom-events recaptcha