我必须为支付网关使用两个外部脚本。

现在两者都放在index.html文件中。

但是,我不想在开头本身就加载这些文件。

只有在用户打开特定组件(使用路由器视图)时才需要支付网关。

有办法实现这个目标吗?

谢谢。


当前回答

如果你试图利用一个在JavaScript文件中定义的变量,而这个文件是异步加载的,你收到一个'undefined'错误,这很可能是因为脚本还没有完成加载。要解决这个问题,可以利用onload函数确保脚本在尝试访问变量之前已经完成加载。举个例子:

const script = document.createElement(...) // set attribute and so on...
script.onload = () => {
  // do something with some variables/functions/logic from the loaded script
}

其他回答

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

好吧,这是我在qiokian(一个live2d动画人物vuejs组件)中的实践:

(以下来自src/qiokian.vue文件)

<script>
export default {
    data() {
        return {
            live2d_path:
                'https://cdn.jsdelivr.net/gh/knowscount/live2d-widget@latest/',
            cdnPath: 'https://cdn.jsdelivr.net/gh/fghrsh/live2d_api/',
        }
    },
<!-- ... -->
        loadAssets() {
            // load waifu.css live2d.min.js waifu-tips.js
            if (screen.width >= 768) {
                Promise.all([
                    this.loadExternalResource(
                        this.live2d_path + 'waifu.css',
                        'css'
                    ),
<!-- ... -->
        loadExternalResource(url, type) {
            // note: live2d_path parameter should be an absolute path
            // const live2d_path =
            //   "https://cdn.jsdelivr.net/gh/knowscount/live2d-widget@latest/";
            //const live2d_path = "/live2d-widget/";
            return new Promise((resolve, reject) => {
                let tag

                if (type === 'css') {
                    tag = document.createElement('link')
                    tag.rel = 'stylesheet'
                    tag.href = url
                } else if (type === 'js') {
                    tag = document.createElement('script')
                    tag.src = url
                }
                if (tag) {
                    tag.onload = () => resolve(url)
                    tag.onerror = () => reject(url)
                    document.head.appendChild(tag)
                }
            })
        },
    },
}

我下载了一些HTML模板,附带自定义js文件和jquery。我必须将这些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")

为了保持组件的干净,你可以使用mixin。

在组件上导入外部mixin文件。

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",
       }
     }
    ]
}

解决这个问题的一个简单而有效的方法是将外部脚本添加到组件的vue mounted()中。我将用谷歌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