推迟执行,直到在Vue.js中加载了外部脚本

Mih*_*hai 4 javascript javascript-events recaptcha vue.js vuejs2

我想recaptchaVue.js组件安装后渲染一个。它可以正常加载和重新加载,但是当我导航到其他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>
Run Code Online (Sandbox Code Playgroud)

在正常页面上,加载/重新加载正常this.render()执行。但是,当我导航到另一个url并通过后退按钮返回时,会得到:Error in nextTick: "TypeError: window.grecaptcha.render is not a function"

我尝试过了:

  • onloadapi脚本事件上设置一个变量:

    <script src='...' onload="window.script = { recaptcha: 'ready' }" async></script>

  • 然后将其添加为一个属性data()Recaptcha.vue

    ready: window.script.recaptcha

  • 接下来,我在ready媒体资源上添加了一个观察者,并在其中尝试运行该观察者this.render()

没有成功,错误仍然存​​在。我认为,即使在正常的加载/重新加载情况下,我也很“幸运”地知道api脚本在组件安装之前就已加载,并且放置this.render()mounted()钩子中没有帮助。

您知道我如何发信号Recaptcha.vue表示外部脚本已完成加载,然后才渲染recaptcha

LSh*_*apz 6

好的,这是一个理论:添加数据属性

captchaReady: false, 
checkingInterval: null,
Run Code Online (Sandbox Code Playgroud)

被创造

let localThis = this 
this.checkingInterval = setInterval(function(){
  if (window.grecaptcha) {
    localThis.captchaReady = true
  }
}, 500) //or whatever interval you want to check 
Run Code Online (Sandbox Code Playgroud)

然后

watch: {
  captchaReady: function(data) {
    if (data) { 
       clearInterval(this.checkingInterval) 
       this.render()
    }
  }
}
Run Code Online (Sandbox Code Playgroud)