I am programmatically adding necessary scripts into some of my Vue components, like so:
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);
},
Now, I noticed that if I navigate away from the component and back into it, without refreshing the page wholesale, that Vue will start loading in duplicate copies of the things I attach in that mounted()
call. So I wanted to clean them up as follows:
beforeDestroy() {
const gsc = document.getElementById('grecaptchascript');
gsc.parentElement.removeChild(gsc);
},
However it seems like the id
of that script is never even set, so the cleanup step fails silently.
Am I doing it totally wrong? Is a better pattern for doing this? If not, why isn't my <script>
getting the id
I'm setting?
Footnote: I am aware that using an id
is problematic here since we're talking about duplicated elements. I'll change this later. Please consider the general case of selecting by any arbitrary attribute, if that helps. I've tried other attributes but with no success.
I think that such cleaning is not necessary: after loading the script all definitions of functions and variables fall into the global scope, and after unloading the script they are not deleted.
What you need is to check that the scripts are already loaded, and do not load more than once:
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);
}
}