vue.js props Comment ajouter des scripts JS externes aux composants VueJS




vuejs component register (7)

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 avec 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

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?


Answer #1

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é.


Answer #2

Utilisez-vous l’un des modèles de départ Webpack pour une 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 partir de vos scripts ce que vous souhaitez import dans 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


Answer #3

La meilleure réponse de create tag in mount 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>

......

Answer #4

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.


Answer #5

J'ai téléchargé un modèle HTML fourni avec des 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")

Answer #6

Vous pouvez utiliser le paquet 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 },
      // ...
    ]
  }
})

Consultez ce link pour plus d'exemples.