【问题标题】:Defer execution until external script has loaded in Vue.js推迟执行,直到外部脚本加载到 Vue.js 中
【发布时间】: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事件上设置一个变量:

    &lt;script src='...' onload="window.script = { recaptcha: 'ready' }" async&gt;&lt;/script&gt;

  • 然后将其作为属性添加到Recaptcha.vuedata() 中:

    ready: window.script.recaptcha

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

没有成功,错误依然存在。我认为即使在正常的加载/重新加载情况下,我也只是“幸运”了 api 脚本在组件安装之前加载,并且将 this.render() 放在 mounted() 钩子内没有帮助。

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

【问题讨论】:

  • 通常只使用asyncdefer,不能同时使用。
  • 已更正,谢谢。
  • 感谢您的建议,但这并不能真正回答我的问题。我更喜欢一种更简单的方法来指示脚本已加载的组件。

标签: javascript vue.js vuejs2 dom-events recaptcha


【解决方案1】:

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

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()
    }
  }
}

【讨论】:

  • 看起来很有趣,我正在尝试! captchaReady: function(data) 中的 data 参数是什么?
  • 监视函数采用一个参数,该参数是被监视属性的值。在(Vue 文档中,他们称之为val) - 所以if (data) 表示if (this.captchaReady === true) vuejs.org/v2/guide/computed.html#Computed-vs-Watched-Property
  • 啊,完全忘记了。它有效,而且非常巧妙。标记为已接受。干杯!
猜你喜欢
  • 2015-03-30
  • 1970-01-01
  • 2014-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-01
  • 2019-04-08
相关资源
最近更新 更多