我正在以编程方式将必要的脚本添加到我的一些Vue组件中,如下所示:
mounted() {
const
googleRecaptchaScript = document.createElement('script'),
recaptchaURL = 'https://www.google.com/recaptcha/api.js';
googleRecaptchaScript.setAttribute('src', recaptchaURL);
googleRecaptchaScript.setAttribute('id', 'grecaptchascript');
document.head.appendChild(googleRecaptchaScript);
},
现在,我注意到如果我离开组件并返回到它,而不刷新页面批发,那么Vue将开始加载我在mounted()
调用中附加的内容的重复副本。所以我想按照以下方式清理它们:
beforeDestroy() {
const gsc = document.getElementById('grecaptchascript');
gsc.parentElement.removeChild(gsc);
},
然而,似乎该脚本的id
从未设置过,因此清理步骤无声地失败。
我完全错了吗?这样做是一个更好的模式吗?如果没有,为什么<script>
我的id
设置不正常?
脚注:我知道在这里使用id
是有问题的,因为我们讨论的是重复元素。我稍后会改变它。如果有帮助,请考虑通过任意属性进行选择的一般情况。我尝试了其他属性但没有成功。
答案 0 :(得分:1)
我认为没有必要进行这样的清理:在加载脚本之后,所有函数和变量的定义都属于全局范围,卸载脚本后它们不会被删除。
您需要检查脚本是否已加载,并且不要加载多次:
mounted() {
const gsc = document.getElementById('grecaptchascript');
if (!gsc) {
const
googleRecaptchaScript = document.createElement('script'),
recaptchaURL = 'https://www.google.com/recaptcha/api.js';
googleRecaptchaScript.setAttribute('src', recaptchaURL);
googleRecaptchaScript.setAttribute('id', 'grecaptchascript');
document.head.appendChild(googleRecaptchaScript);
}
}
答案 1 :(得分:0)
我不确定问题到底是什么,但是为了将来参考,这个解决方案有效并且对我的情况看起来相当不错,因为它选择了src
的{{1}}属性的前缀:
mounted() {
const
googleRecaptchaScript = document.createElement('script'),
recaptchaURL = `https://www.google.com/recaptcha/api.js?hl=${this.$i18n.locale}`;
googleRecaptchaScript.setAttribute('src', recaptchaURL);
document.head.appendChild(googleRecaptchaScript);
},
beforeDestroy() {
const recaptchaScripts = document.querySelectorAll('script[src^="https://www.google.com/recaptcha/api.js"]');
for (let i = 0; i < recaptchaScripts.length; i += 1) {
recaptchaScripts[i].parentElement.removeChild(recaptchaScripts[i]);
}
},
我很确定id
也会很好,我只是愚蠢。如果有人有更好的解决方案,我仍然会感兴趣,因为“手动”(以编程方式)从页面中选择和删除元素似乎有点脏。