web-dev-qa-db-ja.com

外部のJSスクリプトをVueJSコンポーネントに追加する方法

支払いゲートウェイに2つの外部スクリプトを使用します。今のところ両方とも 'index.html'ファイルに入れられています。しかし、私は最初からこれらのファイルをロードしたくありません。ペイメントゲートウェイは、ユーザーが特定のコンポーネントを開いたときにのみ必要です(ルータービューを使用)。これを達成するためにとにかくありますか?

71
Gijo Varghese

これを解決する簡単で効果的な方法は、あなたのコンポーネントの値mounted()にあなたの外部スクリプトを追加することです。 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>

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

109
mejiamanuel57

webPackとVueローダーを使用してあなたはこのようなことをすることができます

コンポーネントを作成する前に外部スクリプトがロードされるのを待つので、globar varsなどがコンポーネントで利用可能です。

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)
  })
 }
},
12
mons droid

私はカスタムのjsファイルとjqueryが付属しているいくつかのHTMLテンプレートをダウンロードしました。私は自分のアプリにそれらのjsを添付しなければなりませんでした。そしてVueを続けてください。

このプラグインが見つかりました、それはCDNを通してそして静的ファイル の両方から外部スクリプトを追加するためのきれいな方法です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")
10
PJ3

あなたはvue用のWebpackスターターテンプレートの1つを使用していますか( https://github.com/vuejs-templates/webpack )。それはすでにvue-loader( https://github.com/vuejs/vue-loader )で設定されています。スターターテンプレートを使用していない場合は、webpackとvue-loaderを設定する必要があります。

スクリプトをimportして、関連する(単一ファイル)コンポーネントにすることができます。その前に、あなたのスクリプトからあなたがあなたのコンポーネントにexportしたいものをtoimportしなければなりません。

ES6のインポート:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
- http://exploringjs.com/es6/ch_modules.html

〜編集〜
これらのラッパーからインポートできます。
- https://github.com/matfish2/vue-stripe
- https://github.com/khoanguyen96/vue-Paypal-checkout

5
ba_ul

約束ベースのソリューションで必要なスクリプトをロードすることができます。

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

    }
  }
}

this.$rootはちょっとした手間がかかるので、グローバルイベントには代わりに vuex または eventHub を使用してください。

あなたは上記のものをコンポーネントにして必要なところでそれを使用するでしょう、それは使用される時にだけスクリプトをロードするでしょう。

3
hitautodestruct

vue-head パッケージを使用して、スクリプトやその他のタグをvueコンポーネントの先頭に追加できます。

そのように簡単です:

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 },
      // ...
    ]
  }
})

他の例については、この リンク をご覧ください。

2
pamekar

あなたは vue-loader を使用してあなたのコンポーネントをそれら自身のファイル(単一ファイルコンポーネント)でコーディングすることができます。これにより、コンポーネントベースでスクリプトとCSSを含めることができます。

1
Daniel D

マウントされたタグの作成の一番の答えは良いですが、いくつかの問題があります:

リンクを複数回変更すると、タグの作成が何度も繰り返されます。

そこで、これを解決するスクリプトを作成しました。必要に応じてタグを削除できます。

非常に簡単ですが、自分で作成する時間を節約できます。

// 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,
}

そして、次のように使用できます。

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

......
0
oraant