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

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

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

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

有办法实现这个目标吗?

谢谢。


当前回答

顶部的创建标签的答案是好的,但它有一些问题:如果你改变你的链接多次,它会重复创建标签一遍又一遍。

所以我创建了一个脚本来解决这个问题,如果你愿意,你可以删除标签。

它非常简单,但可以节省你自己创建的时间。

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

......

其他回答

您可以使用vue-loader并在它们自己的文件中编写组件(单文件组件)。这将允许您在组件的基础上包含脚本和css。

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的Webpack入门模板(https://github.com/vuejs-templates/webpack)?vue-loader (https://github.com/vuejs/vue-loader)已经设置好了。如果你不使用启动器模板,你必须设置webpack和vue-loader。

然后,您可以将脚本导入到相关的(单个文件)组件。在此之前,你必须从脚本中导出你想导入到组件中的内容。

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

如果你正在使用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函数。

更新:这不再工作在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的视频