Je dois utiliser deux scripts externes pour les passerelles de paiement. À l'heure actuelle, les deux sont placés dans le fichier 'index.html'. Cependant, je ne veux pas charger ces fichiers au début. La passerelle de paiement est nécessaire uniquement lorsque l'utilisateur ouvre un composant spécifique (à l'aide de router-view). Y'a-t-il une quelconque façon de réussir cela?
Un moyen simple et efficace de résoudre ce problème consiste à ajouter votre script externe dans la vue mounted()
de votre composant. Je vais vous illustrer par le script Google Recaptcha :
<template>
.... your HTML
</template>
<script>
export default {
data: () => ({
......data of your component
}),
mounted() {
let recaptchaScript = document.createElement('script')
recaptchaScript.setAttribute('src', 'https://www.google.com/recaptcha/api.js')
document.head.appendChild(recaptchaScript)
},
methods: {
......methods of your component
}
}
</script>
Source: https://medium.com/@lassiuosukainen/how-to-include-a-script-tag-on-a-vue-component-fe10940af9e8
en utilisant webpack et vue loader, vous pouvez faire quelque chose comme ceci
il attend que le script externe soit chargé avant de créer le composant, de sorte que les variables globar, etc., sont disponibles dans le composant
components: {
SomeComponent: () => {
return new Promise((resolve, reject) => {
let script = document.createElement(‘script’)
script.onload = () => {
resolve(import(someComponent’))
}
script.async = true
script.src = ‘https://maps.googleapis.com/maps/api/js?key=APIKEY&libraries=places’
document.head.appendChild(script)
})
}
},
J'ai téléchargé un modèle HTML fourni avec les fichiers js personnalisés et jquery. Je devais attacher ces js à mon application. et continuez avec Vue.
Trouvé ce plugin, c'est un moyen simple d'ajouter des scripts externes à la fois via CDN et à partir de fichiers statiques https://www.npmjs.com/package/vue-plugin-load-script
// local files
// you have to put your scripts into the public folder.
// that way webpack simply copy these files as it is.
Vue.loadScript("/js/jquery-2.2.4.min.js")
// cdn
Vue.loadScript("https://maps.googleapis.com/maps/api/js")
Utilisez-vous l’un des modèles de départ Webpack pour vue ( https://github.com/vuejs-templates/webpack )? Il est déjà configuré avec vue-loader ( https://github.com/vuejs/vue-loader ). Si vous n'utilisez pas de modèle de départ, vous devez configurer webpack et vue-loader.
Vous pouvez ensuite import
vos scripts dans les composants appropriés (fichier unique). Avant cela, vous devez export
parmi vos scripts ce que vous voulez import
à vos composants.
ES6 importation:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
- http://exploringjs.com/es6/ch_modules.html
~ Modifier ~
Vous pouvez importer à partir de ces wrappers:
- https://github.com/matfish2/vue-stripe
- https://github.com/khoanguyen96/vue-Paypal-checkout
Vous pouvez utiliser le paquetage vue-head pour ajouter des scripts et d’autres balises à l’en-tête de votre composant vue.
C'est aussi simple que:
var myComponent = Vue.extend({
data: function () {
return {
...
}
},
head: {
title: {
inner: 'It will be a pleasure'
},
// Meta tags
meta: [
{ name: 'application-name', content: 'Name of my application' },
{ name: 'description', content: 'A description of the page', id: 'desc' }, // id to replace intead of create element
// ...
// Twitter
{ name: 'Twitter:title', content: 'Content Title' },
// with shorthand
{ n: 'Twitter:description', c: 'Content description less than 200 characters'},
// ...
// Google+ / Schema.org
{ itemprop: 'name', content: 'Content Title' },
{ itemprop: 'description', content: 'Content Title' },
// ...
// Facebook / Open Graph
{ property: 'fb:app_id', content: '123456789' },
{ property: 'og:title', content: 'Content Title' },
// with shorthand
{ p: 'og:image', c: 'https://example.com/image.jpg' },
// ...
],
// link tags
link: [
{ rel: 'canonical', href: 'http://example.com/#!/contact/', id: 'canonical' },
{ rel: 'author', href: 'author', undo: false }, // undo property - not to remove the element
{ rel: 'icon', href: require('./path/to/icon-16.png'), sizes: '16x16', type: 'image/png' },
// with shorthand
{ r: 'icon', h: 'path/to/icon-32.png', sz: '32x32', t: 'image/png' },
// ...
],
script: [
{ type: 'text/javascript', src: 'cdn/to/script.js', async: true, body: true}, // Insert in body
// with shorthand
{ t: 'application/ld+json', i: '{ "@context": "http://schema.org" }' },
// ...
],
style: [
{ type: 'text/css', inner: 'body { background-color: #000; color: #fff}', undo: false },
// ...
]
}
})
Découvrez ceci lien pour plus d'exemples.
Vous pouvez charger le script dont vous avez besoin avec une solution basée sur une promesse:
export default {
data () {
return { is_script_loading: false }
},
created () {
// If another component is already loading the script
this.$root.$on('loading_script', e => { this.is_script_loading = true })
},
methods: {
load_script () {
let self = this
return new Promise((resolve, reject) => {
// if script is already loading via another component
if ( self.is_script_loading ){
// Resolve when the other component has loaded the script
this.$root.$on('script_loaded', resolve)
return
}
let script = document.createElement('script')
script.setAttribute('src', 'https://www.google.com/recaptcha/api.js')
script.async = true
this.$root.$emit('loading_script')
script.onload = () => {
/* emit to global event bus to inform other components
* we are already loading the script */
this.$root.$emit('script_loaded')
resolve()
}
document.head.appendChild(script)
})
},
async use_script () {
try {
await this.load_script()
// .. do what you want after script has loaded
} catch (err) { console.log(err) }
}
}
}
Veuillez noter que this.$root
est un petit hacky et que vous devriez plutôt utiliser une solution vuex ou eventHub pour les événements globaux.
Vous feriez de ce qui précède un composant et l'utilisez où vous le souhaitez, il ne chargera le script que s'il est utilisé.
Vous pouvez utiliser vue-loader et coder vos composants dans leurs propres fichiers (composants à fichier unique). Cela vous permettra d'inclure des scripts et des CSS sur une base de composant.
Pour garder des composants propres, vous pouvez utiliser mixins.
Sur votre composant, importez un fichier de mixage externe.
Profile.vue
import externalJs from '@client/mixins/externalJs';
export default{
mounted(){
this.externalJsFiles();
}
}
externalJs.js
import('@JSassets/js/file-upload.js').then(mod => {
// your JS elements
})
babelrc (j'inclus ceci, le cas échéant bloqué à l'importation)
{
"presets":["@babel/preset-env"],
"plugins":[
[
"module-resolver", {
"root": ["./"],
alias : {
"@client": "./client",
"@JSassets": "./server/public",
}
}
]
}
La première réponse de create tag in monté est bonne, mais elle pose quelques problèmes:
Si vous modifiez votre lien plusieurs fois, il répète inlassablement la création de la balise.
J'ai donc créé un script pour résoudre ce problème, et vous pouvez supprimer la balise si vous le souhaitez.
C'est très simple, mais vous pouvez économiser du temps pour le créer vous-même.
// PROJECT/src/assets/external.js
function head_script(src) {
if(document.querySelector("script[src='" + src + "']")){ return; }
let script = document.createElement('script');
script.setAttribute('src', src);
script.setAttribute('type', 'text/javascript');
document.head.appendChild(script)
}
function body_script(src) {
if(document.querySelector("script[src='" + src + "']")){ return; }
let script = document.createElement('script');
script.setAttribute('src', src);
script.setAttribute('type', 'text/javascript');
document.body.appendChild(script)
}
function del_script(src) {
let el = document.querySelector("script[src='" + src + "']");
if(el){ el.remove(); }
}
function head_link(href) {
if(document.querySelector("link[href='" + href + "']")){ return; }
let link = document.createElement('link');
link.setAttribute('href', href);
link.setAttribute('rel', "stylesheet");
link.setAttribute('type', "text/css");
document.head.appendChild(link)
}
function body_link(href) {
if(document.querySelector("link[href='" + href + "']")){ return; }
let link = document.createElement('link');
link.setAttribute('href', href);
link.setAttribute('rel', "stylesheet");
link.setAttribute('type', "text/css");
document.body.appendChild(link)
}
function del_link(href) {
let el = document.querySelector("link[href='" + href + "']");
if(el){ el.remove(); }
}
export {
head_script,
body_script,
del_script,
head_link,
body_link,
del_link,
}
Et vous pouvez l'utiliser comme ceci:
// PROJECT/src/views/xxxxxxxxx.vue
......
<script>
import * as external from '@/assets/external.js'
export default {
name: "xxxxxxxxx",
mounted(){
external.head_script('/assets/script1.js');
external.body_script('/assets/script2.js');
external.head_link('/assets/style1.css');
external.body_link('/assets/style2.css');
},
destroyed(){
external.del_script('/assets/script1.js');
external.del_script('/assets/script2.js');
external.del_link('/assets/style1.css');
external.del_link('/assets/style2.css');
},
}
</script>
......