The correct answer is that it depends on the third-party library, the ways it provides for installation and if it has integration support with Vue.js and/or Quasar.
For example for Stripe, you can install it as an npm package and use it like this (non-tested code):
<script setup>
import { onMounted } from 'vue'
import {loadStripe} from '@stripe/stripe-js';
onMounted(() => {
const stripe = await loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx');
})
</script>
Third-party library with script tag installation
I am going to assume though, that the question is more on how to add a third-party library that provides only a script tag installation:
- Create a JS file (load-script.js):
function createTag(src) {
let script
script = document.createElement('script')
script.type = 'application/javascript'
script.async = true
script.src = src
return script
}
function addListeners(script, resolve, reject) {
script.addEventListener('error', reject)
script.addEventListener('abort', reject)
script.addEventListener('load', function loadScriptHandler() {
script.setAttribute('data-loaded', '')
resolve(removeScript.bind(null, script))
})
}
export function removeScript(scriptOrSrc) {
let script
if (typeof scriptOrSrc === 'string') {
script = document.querySelector(`script[src="${scriptOrSrc}"]`)
} else {
script = scriptOrSrc
}
if (script) script.parentNode.removeChild(script)
}
export function loadScript(src) {
return new Promise((resolve, reject) => {
let script = document.querySelector(`script[src="${src}"]`)
if (script && script.hasAttribute('data-loaded')) {
resolve(removeScript.bind(null, script))
return
}
script = createTag(src)
addListeners(script, resolve, reject)
document.head.appendChild(script)
})
}
- Use that function to load or remove script tag in your components:
<script setup>
import { onUnmounted } from 'vue'
import { loadScript, removeScript } from '../load-script'
const src = '3rd-part-url'
loadScript(src)
onUnmounted(() => removeScript(src))
</script>
With .then approach:
<script setup>
import { onUnmounted } from 'vue'
import { loadScript } from '../load-script'
let removeScript
loadScript('3rd-part-url').then((removeScriptCallback) => {
// script is loaded use `removeScriptCallback()` to remove it
removeScript = removeScriptCallback
})
onUnmounted(() => removeScript())
</script>
with Options API:
<script>
import { loadScript, removeScript } from './load-script.js'
export default {
created() {
this.externalScriptUrl = '...'
loadScript(externalScriptUrl).then(removeScript => {
// script is loaded use `removeScript()` to remove it
})
},
unmounted() {
removeScript(this.externalScriptUrl)
}
}
</script>
Explanation
The load-script.js file uses async attribute.
It registers error, abort and load events for the script tag. Then load event resolves the then block whereas error and abort fall in the catch block of the promise. AFAIK since events are registered in the element there is no need to remove listeners.
The script tag will be appended in the head.
The script can be easily enhanced by adding support for script attributes or to be able to append it in body but for the purpose of this answer, it's better to keep it simple.
Things to know
- You may or may not have security issues loading external js on the fly.
- Removing the script tag, doesn't mean you unloaded the script:
any code loaded as part of the external JavaScript file remains in the browser's memory. That is to say, you can still access variables, functions etc that were added when the external file first loaded