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

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

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

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

有办法实现这个目标吗?

谢谢。


当前回答

解决这个问题的一个简单而有效的方法是将外部脚本添加到组件的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

其他回答

mounted() {
    if (document.getElementById('myScript')) { return }
    let src = 'your script source'
    let script = document.createElement('script')
    script.setAttribute('src', src)
    script.setAttribute('type', 'text/javascript')
    script.setAttribute('id', 'myScript')
    document.head.appendChild(script)
}


beforeDestroy() {
    let el = document.getElementById('myScript')
    if (el) { el.remove() }
}

在Vue 3中,我使用mejiamanuel57回答,并附加了一个检查,以确保脚本标记尚未加载。

    mounted() {
        const scripts = [
            "js/script1.js",
            "js/script2.js"
        ];
        scripts.forEach(script => {
            let tag = document.head.querySelector(`[src="${ script }"`);
            if (!tag) {
                tag = document.createElement("script");
                tag.setAttribute("src", script);
                tag.setAttribute("type", 'text/javascript');
                document.head.appendChild(tag); 
            }
        });
    // ...

更新:这不再工作在Vue 3。你会收到这样的错误:

VueCompilerError:在客户端组件模板中忽略带有副作用(和)的标签。


如果你试图将外部js脚本嵌入vue.js组件模板,请遵循以下步骤:

我想向我的组件添加一个外部JavaScript嵌入代码,如下所示:

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

Vue显示了这个错误:

模板应该只负责将状态映射到UI。避免在模板中放置带有副作用的标记,例如,因为它们不会被解析。


我解决这个问题的方法是通过添加type="application/javascript"(参见这个问题了解更多关于js的MIME类型):

<script type="application/javascript" defer src="…"" > < > /脚本


您可能会注意到defer属性。如果你想了解更多,请观看Kyle的视频

为了保持组件的干净,你可以使用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 3和Composition API(我强烈推荐),并且你经常使用<script>标记,你可以为它写一个“composable”函数:

import { onMounted } from "vue";

export const useScript = (src, async = false, defer = false) => {
  onMounted(() => {
    // check if script already exists
    if (document.querySelector(`head script[src="${src}"`)) return;

    // add tag to head
    const tag = document.createElement("script");
    tag.setAttribute("src", src);
    if (async) tag.setAttribute("async", "");
    if (defer) tag.setAttribute("defer", "");
    tag.setAttribute("type", "text/javascript");
    document.head.append(tag);
  });
};

或者,如果你正在使用VueUse(我也强烈推荐),你可以使用他们现有的useScriptTag函数。