我必须为支付网关使用两个外部脚本。
现在两者都放在index.html文件中。
但是,我不想在开头本身就加载这些文件。
只有在用户打开特定组件(使用路由器视图)时才需要支付网关。
有办法实现这个目标吗?
谢谢。
我必须为支付网关使用两个外部脚本。
现在两者都放在index.html文件中。
但是,我不想在开头本身就加载这些文件。
只有在用户打开特定组件(使用路由器视图)时才需要支付网关。
有办法实现这个目标吗?
谢谢。
当前回答
更新:这不再工作在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的视频
其他回答
来自mejiamanuel57的答案很好,但我想添加几个适合我的技巧(我花了几个小时在上面)。首先,我需要使用“窗口”范围。此外,如果您需要访问“onload”函数内的任何Vue元素,则需要为“this”实例创建一个新变量。
<script>
import { mapActions } from "vuex";
export default {
name: "Payment",
methods: {
...mapActions(["aVueAction"])
},
created() {
let paywayScript = document.createElement("script");
let self = this;
paywayScript.onload = () => {
// call to Vuex action.
self.aVueAction();
// call to script function
window.payway.aScriptFunction();
};
// paywayScript.async = true;
paywayScript.setAttribute(
"src",
"https://api.payway.com.au/rest/v1/payway.js"
);
document.body.appendChild(paywayScript);
}
};
</script>
我在Vue 2.6上使用它。这里有一个关于“let self = this;”在Javascript中如何工作的技巧的解释:
var that = this;在JavaScript中是什么意思?
更新:这不再工作在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的视频
您可以使用vue-loader并在它们自己的文件中编写组件(单文件组件)。这将允许您在组件的基础上包含脚本和css。
如果你试图利用一个在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
}
你可以加载你需要的基于承诺的解决方案的脚本:
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) }
}
}
}
请注意这一点。$root有点粗糙,对于全局事件,您应该使用vuex或甚至enthub解决方案。
你可以把上面的内容变成一个组件,并在任何需要的地方使用它,它只会在使用时加载脚本。
注意:这是一台Vue 2。基于X的解。Vue 3已停止支持$on。