Javascript 如何将外部 JS 脚本添加到 VueJS 组件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45047126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add external JS scripts to VueJS Components
提问by Gijo Varghese
I've to use two external scripts for the payment gateways. Right now both are put in the index.htmlfile. However, I don't want to load these files at the beginning itself. The payment gateway is needed only in when user open a specific component (using router-view).
我必须为支付网关使用两个外部脚本。现在两者都放在index.html文件中。但是,我不想在一开始就加载这些文件。仅当用户打开特定组件 ( using router-view)时才需要支付网关。
Is there anyway to achieve this?
有没有办法实现这一目标?
回答by mejiamanuel57
A simple and effective way to solve this, it's by adding your external script into the vue mounted()of your component. I will illustrate you with the Google Recaptchascript:
解决这个问题的一个简单有效的方法是将外部脚本添加到mounted()组件的 vue中。我将用Google 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>
Source: https://medium.com/@lassiuosukainen/how-to-include-a-script-tag-on-a-vue-component-fe10940af9e8
来源:https: //medium.com/@lassiuosukainen/how-to-include-a-script-tag-on-a-vue-component-fe10940af9e8
回答by PJ3
I have downloaded some HTML template that comes with custom js files and jquery. I had to attach those js to my app. and continue with Vue.
我已经下载了一些带有自定义 js 文件和 jquery 的 HTML 模板。我不得不将这些 js 附加到我的应用程序中。并继续使用 Vue。
Found this plugin, it's a clean way to add external scripts both via CDN and from static files https://www.npmjs.com/package/vue-plugin-load-script
找到了这个插件,这是一种通过 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")
回答by mons droid
using webpack and vue loader you can do something like this
使用 webpack 和 vue loader 你可以做这样的事情
it waits for the external script to load before creating the component, so globar vars etc are available in the component
它在创建组件之前等待外部脚本加载,因此组件中可以使用全局变量等
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)
? })
}
},
回答by ba_ul
Are you using one of the Webpack starter templates for vue (https://github.com/vuejs-templates/webpack)? It already comes set up with vue-loader (https://github.com/vuejs/vue-loader). If you're not using a starter template, you have to set up webpack and vue-loader.
您是否使用 vue 的 Webpack 入门模板之一(https://github.com/vuejs-templates/webpack)?它已经设置了 vue-loader ( https://github.com/vuejs/vue-loader)。如果您没有使用入门模板,则必须设置 webpack 和 vue-loader。
You can then importyour scripts to the relevant (single file) components. Before that, you have toexportfrom your scripts what you want to importto your components.
然后您可以将import您的脚本添加到相关(单个文件)组件中。在此之前,您必须export从脚本中获得您想要import的组件。
ES6 import:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
- http://exploringjs.com/es6/ch_modules.html
ES6 导入:
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
- http://exploringjs.com/es6/ch_modules.html
~Edit~
You can import from these wrappers:
- https://github.com/matfish2/vue-stripe
- https://github.com/khoanguyen96/vue-paypal-checkout
~编辑~
你可以从这些包装器导入:
- https://github.com/matfish2/vue-stripe
- https://github.com/khoanguyen96/vue-paypal-checkout
回答by pamekar
You can use the vue-headpackage to add scripts, and other tags to the head of your vue component.
您可以使用vue-head包将脚本和其他标签添加到 vue 组件的头部。
Its as simple as:
它很简单:
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 },
// ...
]
}
})
Check out this linkfor more examples.
查看此链接以获取更多示例。
回答by hitautodestruct
You can load the script you need with a promise based solution:
您可以使用基于承诺的解决方案加载您需要的脚本:
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) }
}
}
}
Please note that this.$rootis a little hacky and you should use a vuexor eventHubsolution for the global events instead.
请注意,this.$root这有点麻烦,您应该为全局事件使用vuex或eventHub解决方案。
You would make the above into a component and use it wherever needed, it will only load the script when used.
您可以将上述内容制作成一个组件并在需要的地方使用它,它只会在使用时加载脚本。
回答by roli roli
If you are trying to embed external js scripts to the vue.js component template, follow below:
如果您尝试将外部 js 脚本嵌入到 vue.js 组件模板中,请按照以下步骤操作:
I wanted to add a external javascript embed codeto my component like this:
我想向我的组件添加一个外部 javascript 嵌入代码,如下所示:
<template>
<div>
This is my component
<script src="https://badge.dimensions.ai/badge.js"></script>
</div>
<template>
And Vue showed me this error:
Vue 向我展示了这个错误:
Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as , as they will not be parsed.
模板应该只负责将状态映射到 UI。避免在模板中放置带有副作用的标签,例如 ,因为它们不会被解析。
The way I solved it was by adding
type="application/javascript"(See this question to learn more about MIME type for js):
我解决它的方法是添加
type="application/javascript"(请参阅此问题以了解有关 js 的 MIME 类型的更多信息):
<script type="application/javascript" defer src="..."></script>
<script type="application/javascript" defer src="..."></script>
You may notice the deferattribute. If you want to learn more watch this video by Kyle
您可能会注意到该defer属性。如果您想了解更多信息,请观看Kyle 的此视频
回答by Daniel D
You can use vue-loaderand code your components in their own files (Single file components). This will allow you to include scripts and css on a component basis.
您可以使用vue-loader并将您的组件编码到它们自己的文件中(单文件组件)。这将允许您在组件的基础上包含脚本和 css。
回答by oraant
The top answer of create tag in mounted is good, but it has some problems: If you change your link multiple times, it will repeat create tag over and over.
在mounted中创建标签的最佳答案是好的,但它有一些问题:如果多次更改链接,它会一遍又一遍地重复创建标签。
So I created a script to resolve this, and you can delete the tag if you want.
所以我创建了一个脚本来解决这个问题,如果你愿意,你可以删除标签。
It's very simple, but can save your time to create it by yourself.
这很简单,但可以节省您自己创建的时间。
// 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,
}
And you can use it like this:
你可以像这样使用它:
// 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>
......
回答by Tushar Roy
To keep clean components you can use mixins.
为了保持干净的组件,您可以使用 mixins。
On your component import external mixin file.
在您的组件上导入外部 mixin 文件。
Profile.vue
配置文件.vue
import externalJs from '@client/mixins/externalJs';
export default{
mounted(){
this.externalJsFiles();
}
}
externalJs.js
外部Js.js
import('@JSassets/js/file-upload.js').then(mod => {
// your JS elements
})
babelrc (I include this, if any get stuck on import)
babelrc(我包括这个,如果有任何卡在导入)
{
"presets":["@babel/preset-env"],
"plugins":[
[
"module-resolver", {
"root": ["./"],
alias : {
"@client": "./client",
"@JSassets": "./server/public",
}
}
]
}

