推迟执行,直到外部脚本加载 Vue.js
Defer execution until external script has loaded in Vue.js
我想在安装 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
和 return 时,我得到: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()
没有成功,错误依然存在。我认为即使在正常的加载/重新加载情况下,我也只是 "lucky" api
脚本在组件安装之前加载,并且将 this.render()
放在 mounted()
钩子中没有帮助。
你知道我如何发出 Recaptcha.vue
外部脚本加载完成的信号,然后才渲染 recaptcha
吗?
好吧,这是一个理论:添加数据属性
captchaReady: false,
checkingInterval: null,
创建
let localThis = this
this.checkingInterval = setInterval(function(){
if (window.grecaptcha) {
localThis.captchaReady = true
}
}, 500) //or whatever interval you want to check
然后
watch: {
captchaReady: function(data) {
if (data) {
clearInterval(this.checkingInterval)
this.render()
}
}
}
我想在安装 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
和 return 时,我得到: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()
没有成功,错误依然存在。我认为即使在正常的加载/重新加载情况下,我也只是 "lucky" api
脚本在组件安装之前加载,并且将 this.render()
放在 mounted()
钩子中没有帮助。
你知道我如何发出 Recaptcha.vue
外部脚本加载完成的信号,然后才渲染 recaptcha
吗?
好吧,这是一个理论:添加数据属性
captchaReady: false,
checkingInterval: null,
创建
let localThis = this
this.checkingInterval = setInterval(function(){
if (window.grecaptcha) {
localThis.captchaReady = true
}
}, 500) //or whatever interval you want to check
然后
watch: {
captchaReady: function(data) {
if (data) {
clearInterval(this.checkingInterval)
this.render()
}
}
}