Cómo añadir scripts JS externos a los componentes de VueJS


Tengo que usar dos scripts externos para las pasarelas de pago. En este momento ambos se ponen en el 'índice.archivo html. Sin embargo, no quiero cargar estos archivos al principio. La pasarela de pago solo se necesita cuando el usuario abre un componente específico (utilizando router-view). ¿Hay alguna manera de lograr esto?

Author: Gijo Varghese, 2017-07-12

5 answers

Una manera simple y efectiva de resolver esto, es agregando su script externo al vue mounted() de su componente. Te ilustraré con el 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>

Fuente: https://medium.com/@lassiuosukainen/how-to-include-a-script-tag-on-a-vue-component-fe10940af9e8

 48
Author: mejiamanuel57,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-17 19:12:30

Usando webpack y vue loader puedes hacer algo como esto

Espera a que el script externo se cargue antes de crear el componente, por lo que globar vars etc están disponibles en el componente

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)
  })
 }
},
 6
Author: mons droid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-15 17:57:56

Está utilizando una de las plantillas de inicio de Webpack para vue ( https://github.com/vuejs-templates/webpack )? Ya viene configurado con vue-loader ( https://github.com/vuejs/vue-loader). Si no está utilizando una plantilla de inicio, debe configurar webpack y vue-loader.

Luego puede import sus scripts a los componentes relevantes (de un solo archivo). Antes de eso, tienes que export de tus scripts lo que quieres import a tus componentes.

ES6 importación:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
- http://exploringjs.com/es6/ch_modules.html

~ Editar~
Puedes importar desde estas envolturas:
- https://github.com/matfish2/vue-stripe
- https://github.com/khoanguyen96/vue-paypal-checkout

 5
Author: ba_ul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-17 17:13:39

Puede usar vue-loader y codificar sus componentes en sus propios archivos (Componentes de un solo archivo). Esto le permitirá incluir scripts y css en base a componentes.

 2
Author: Daniel D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-12 02:31:10

Puede cargar el script que necesita con una solución basada en promesas:

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) }

    }
  }
}

Tenga en cuenta que this.$root es un poco pirateado y debe usar una solución vuex o EventHub para los eventos globales en su lugar.

Haría lo anterior en un componente y lo usaría donde sea necesario, solo cargará el script cuando se use.

 2
Author: hitautodestruct,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-18 07:14:10