VJJS घटकों में बाहरी जेएस स्क्रिप्ट कैसे जोड़ें


151

मुझे भुगतान गेटवे के लिए दो बाहरी स्क्रिप्ट का उपयोग करना है। अभी दोनों को index.htmlफाइल में डाला गया है । हालाँकि, मैं शुरुआत में ही इन फाइलों को लोड नहीं करना चाहता। भुगतान गेटवे की आवश्यकता केवल तभी होती है जब उपयोगकर्ता एक विशिष्ट घटक ( using router-view) खोलते हैं ।

क्या इसे प्राप्त करने का कोई तरीका है?


क्या आप /public/index.htmlइसे करने के लिए उपयोग कर सकते हैं ?
user3290525

जवाबों:


239

इसे हल करने का एक सरल और प्रभावी तरीका है, यह आपके बाहरी स्क्रिप्ट को mounted()आपके घटक की प्रतिज्ञा में जोड़कर है । मैं आपको Google रिकैप्टा स्क्रिप्ट के साथ समझाऊंगा :

<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


22
created()विधि दस्तावेज़ प्राप्त नहीं कर सकती है, mounted()इसके बजाय का उपयोग करें
Barlas Apaydin

15
recaptchaScript.async = trueइसे सिर पर लगाने से पहले जोड़ें ।
जो आइफर्ट

6
recaptchaScript.defer = trueकिसी के लिए भी उपयुक्त हो सकता है
तारासोचिक

3
यह सुनिश्चित करने के लिए सबसे अच्छा उत्तर है क्योंकि vue का इरादा एकल फ़ाइल घटक फ्रेमवर्क है। जब तक आपकी वर्तमान सम्‍मिलित फ़ाइल बहुत बड़ी नहीं होती है, तब तक मैं आपके लिपि टैग में आपके आरोहित () और / या पहले () खंडों को जोड़ने का सुझाव दूंगा ... कृपया vuejs.org/v2/apn/#beforeMount तय करने से पहले देखें
काइल जोकेल

1
@KeisukeNagakawa सैद्धांतिक रूप से, हाँ। इस उत्तर को देखें stackoverflow.com/questions/1605899/…
जेफ रयान

28

मैंने कुछ HTML टेम्पलेट डाउनलोड किए हैं जो कस्टम js फ़ाइलों और jquery के साथ आते हैं। मुझे उन js को अपने ऐप पर अटैच करना था। और Vue के साथ जारी रखें।

इस प्लगइन को मिला, यह सीडीएन के माध्यम से और स्थिर फ़ाइलों से बाहरी लिपियों को जोड़ने का एक साफ तरीका है 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")

यह वास्तव में साफ और सरल तरीका है। मुझे यह तरीका पसंद है
विक्सनसन

25

वेबपैक और वाउ लोडर का उपयोग करके आप ऐसा कुछ कर सकते हैं

यह घटक बनाने से पहले बाहरी स्क्रिप्ट को लोड करने के लिए इंतजार करता है, इसलिए घटक में ग्लोब वर्जन आदि उपलब्ध हैं

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

मैंने इसे घुड़सवार में इस्तेमाल किया
ओरानिट डार

>> "आप इस कोड को कहां रखते हैं?" : यह आपके vuejs घटक के घटक खंड में है।
एडीएम-आईटी

7

क्या आप vue ( https://github.com/vuejs-templates/webpack ) के लिए वेबपैक स्टार्टर टेम्पलेट्स में से एक का उपयोग कर रहे हैं ? यह पहले से ही vue-loader ( https://github.com/vuejs/vue-loader ) के साथ सेट अप आता है । यदि आप स्टार्टर टेम्पलेट का उपयोग नहीं कर रहे हैं, तो आपको वेबपैक और वाउ-लोडर सेट करना होगा।

फिर आप importअपनी स्क्रिप्ट्स को संबंधित (एकल फ़ाइल) घटकों पर ले जा सकते हैं। इससे पहले, आपको exportअपनी स्क्रिप्ट्स से जो आप importअपने घटकों के लिए चाहते हैं।

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


2
ये स्क्रिप्ट पेपाल और स्ट्राइप से हैं। मैं स्थानीय स्तर पर फ़ाइल को डाउनलोड नहीं कर सकता
Gijo वर्गीज

2
क्या ये रैपर आपकी समस्या का समाधान करते हैं? github.com/matfish2/vue-stripe और github.com/khoanguyen96/vue-paypal-checkout
ba_ul

लंगड़ा जवाब ... इस पर स्पष्टीकरण दें कि क्यों
वाउ

6

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

अधिक उदाहरणों के लिए इस लिंक को देखें।


व्हाट्सएप स्टोर का उपयोग करके इस पर क्या लाभ या अंतर है?
काइल जोकेल

6

यदि आप बाहरी js स्क्रिप्ट को vue.js घटक टेम्पलेट में एम्बेड करने का प्रयास कर रहे हैं, तो नीचे का अनुसरण करें:

मैं इस तरह से अपने घटक के लिए एक बाहरी जावास्क्रिप्ट एम्बेड कोड जोड़ना चाहता था :

<template>
  <div>
    This is my component
    <script src="https://badge.dimensions.ai/badge.js"></script>
  </div>
<template>

और Vue ने मुझे यह त्रुटि दिखाई:

यूआई में राज्य की मैपिंग के लिए टेम्प्लेट केवल जिम्मेदार होने चाहिए। अपने टेम्प्लेट में साइड-इफेक्ट्स वाले टैग रखने से बचें, जैसे कि उन्हें पार्स नहीं किया जाएगा।


जिस तरह से मैंने इसे हल किया, उसे जोड़करtype="application/javascript" ( इस सवाल को js के लिए MIME प्रकार के बारे में अधिक जानने के लिए देखें ):

<script type="application/javascript" defer src="..."></script>


आप deferविशेषता देख सकते हैं । यदि आप इस वीडियो को काइल द्वारा और अधिक देखना चाहते हैं


4

आप वादा आधारित समाधान के साथ अपनी ज़रूरत की स्क्रिप्ट लोड कर सकते हैं:

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

यह बस इस तरह से किया जा सकता है।

  created() {
    var scripts = [
      "https://cloudfront.net/js/jquery-3.4.1.min.js",
      "js/local.js"
    ];
    scripts.forEach(script => {
      let tag = document.createElement("script");
      tag.setAttribute("src", script);
      document.head.appendChild(tag);
    });
  }

2

साफ घटकों को रखने के लिए आप मिश्रण का उपयोग कर सकते हैं।

अपने घटक पर बाहरी मिक्सिन फ़ाइल आयात करें।

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 (मैं इसे शामिल करता हूँ, अगर कोई आयात पर अटक जाता है)

{
  "presets":["@babel/preset-env"],
  "plugins":[
    [
     "module-resolver", {
       "root": ["./"],
       alias : {
         "@client": "./client",
         "@JSassets": "./server/public",
       }
     }
    ]
}

2

माउंटेड में टैग बनाने का शीर्ष उत्तर अच्छा है, लेकिन इसमें कुछ समस्याएं हैं: यदि आप कई बार अपना लिंक बदलते हैं, तो यह बार-बार टैग बनाएगा।

इसलिए मैंने इसे हल करने के लिए एक स्क्रिप्ट बनाई, और आप चाहें तो टैग को हटा सकते हैं।

यह बहुत सरल है, लेकिन इसे अपने आप से बनाने के लिए अपना समय बचा सकते हैं।

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

......

2
एक बार एक स्क्रिप्ट भरी हुई है यह पहले से ही स्मृति में है। इसे डोम से हटाने से इसके पदचिह्न नहीं हटते।
danbars

1

आप वाउ-लोडर का उपयोग कर सकते हैं और अपने कंपोनेंट्स को अपनी फाइलों (सिंगल फाइल कंपोनेंट्स) में कोड कर सकते हैं । यह आपको एक घटक के आधार पर स्क्रिप्ट और सीएसएस शामिल करने की अनुमति देगा।


4
ये स्क्रिप्ट पेपाल और स्ट्राइप से हैं। मैं स्थानीय स्तर पर फ़ाइल को डाउनलोड नहीं कर सकता
Gijo वर्गीज

1
लिंक टूट गया है
रॉबर्टो

आप बाहरी स्क्रिप्ट डाउनलोड कर सकते हैं, स्रोत देख सकते हैं, कॉपी / पेस्ट कर सकते हैं।
न्यूनतम

1
@minimallinux धारी और पेपैल के मामले में, जो PCI-DSS का उल्लंघन करेगा। तो ऐसा मत करो।
डंकन जोन्स

0

सरलतम समाधान यह है index.htmlकि अपने vue-project की फ़ाइल में स्क्रिप्ट जोड़ें

index.html:

 <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>vue-webpack</title>
      </head>
      <body>
        <div id="app"></div>
        <!-- start Mixpanel --><script type="text/javascript">(function(c,a){if(!a.__SV){var b=window;try{var d,m,j,k=b.location,f=k.hash;d=function(a,b){return(m=a.match(RegExp(b+"=([^&]*)")))?m[1]:null};f&&d(f,"state")&&(j=JSON.parse(decodeURIComponent(d(f,"state"))),"mpeditor"===j.action&&(b.sessionStorage.setItem("_mpcehash",f),history.replaceState(j.desiredHash||"",c.title,k.pathname+k.search)))}catch(n){}var l,h;window.mixpanel=a;a._i=[];a.init=function(b,d,g){function c(b,i){var a=i.split(".");2==a.length&&(b=b[a[0]],i=a[1]);b[i]=function(){b.push([i].concat(Array.prototype.slice.call(arguments,
    0)))}}var e=a;"undefined"!==typeof g?e=a[g]=[]:g="mixpanel";e.people=e.people||[];e.toString=function(b){var a="mixpanel";"mixpanel"!==g&&(a+="."+g);b||(a+=" (stub)");return a};e.people.toString=function(){return e.toString(1)+".people (stub)"};l="disable time_event track track_pageview track_links track_forms track_with_groups add_group set_group remove_group register register_once alias unregister identify name_tag set_config reset opt_in_tracking opt_out_tracking has_opted_in_tracking has_opted_out_tracking clear_opt_in_out_tracking people.set people.set_once people.unset people.increment people.append people.union people.track_charge people.clear_charges people.delete_user people.remove".split(" ");
    for(h=0;h<l.length;h++)c(e,l[h]);var f="set set_once union unset remove delete".split(" ");e.get_group=function(){function a(c){b[c]=function(){call2_args=arguments;call2=[c].concat(Array.prototype.slice.call(call2_args,0));e.push([d,call2])}}for(var b={},d=["get_group"].concat(Array.prototype.slice.call(arguments,0)),c=0;c<f.length;c++)a(f[c]);return b};a._i.push([b,d,g])};a.__SV=1.2;b=c.createElement("script");b.type="text/javascript";b.async=!0;b.src="undefined"!==typeof MIXPANEL_CUSTOM_LIB_URL?
    MIXPANEL_CUSTOM_LIB_URL:"file:"===c.location.protocol&&"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\/\//)?"https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js":"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";d=c.getElementsByTagName("script")[0];d.parentNode.insertBefore(b,d)}})(document,window.mixpanel||[]);
    mixpanel.init("xyz");</script><!-- end Mixpanel -->
        <script src="/dist/build.js"></script>
      </body>
    </html>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.