외부 JS 스크립트를 VueJS 구성 요소에 추가하는 방법
나는 결제 게이트웨이에 외부 대본을 두 개 사용해야 해.
지금 현재 두 개 모두 그 안에 있다.index.html
파일
하지만, 나는 이 파일들을 처음부터 로드하고 싶지 않다.
사용자가 특정 구성요소를 열 때만 지불 게이트웨이가 필요함(using router-view
).
이것을 성취할 방법이 있을까?
고마워요.
이 문제를 해결하는 간단하고 효과적인 방법은 외부 스크립트를 vue에 추가하는 것이다.mounted()
당신의 구성 요소의구글 Retrifcha 스크립트로 설명하겠다.
<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-to-to-tog-a-script-tag-on-a-vue-component-fef9e8
나는 사용자 정의 js 파일과 jquery와 함께 제공되는 HTML 템플릿을 다운로드했다.나는 그 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")
웹팩과 vue loader를 사용하여 당신은 이와 같은 것을 할 수 있다.
구성 요소를 생성하기 전에 외부 스크립트가 로드될 때까지 대기하므로 구성 요소에서 글로벌 바 등을 사용할 수 있음
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)
})
}
},
업데이트: 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에 매핑하는 작업만 담당해야 한다.구문 분석되지 않으므로 , 같은 부작용이 있는 태그를 템플릿에 배치하지 마십시오.
내가 해결한 방법은 (js용 MIME 유형에 대해 자세히 알아보려면 이 질문을 참조하십시오):
<script type="application/javascript" defer src="..."></script>
당신은 그것을 알아차릴 수 있을 것이다.defer
기여하다더 많은 것을 알고 싶다면 카일의 이 비디오를 보아라.
이것은 간단히 이렇게 할 수 있다.
created() {
var scripts = [
"https://cloudfront.net/js/jquery-3.4.1.min.js",
"js/local.js"
];
scripts.forEach(script => {
let tag = document.createElement("script");
tag.setAttribute("src", script);
document.head.appendChild(tag);
});
}
약속 기반 솔루션을 사용하여 필요한 스크립트를 로드할 수 있음:
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) }
}
}
}
참고하십시오.this.$root
좀 진부하고 당신은 글로벌 이벤트에 vuex나 eventHub 솔루션을 사용해야 한다.
위 사항을 컴포넌트로 만들어서 필요할 때마다 사용할 수 있고, 사용할 때만 스크립트를 로드할 수 있다.
참고: 이것은 Vue 2.x 기반 솔루션이다.Vue 3은 지원을 중단했다.
vue용 Webpack 스타터 템플릿 중 하나를 사용하십니까(https://github.com/vuejs-templates/webpack)?이미 vue-loader(https://github.com/vuejs/vue-loader))가 설치되어 있다.스타터 템플릿을 사용하지 않는 경우 웹 팩과 vue-loader를 설정해야 한다.
그때 너는 할 수 있다.import
관련(단일 파일) 구성 요소에 대한 스크립트그 전에 해야 한다.export
원하는 대로 스크립트에서import
구성 요소에 연결하십시오.
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-head 패키지를 사용하여 스크립트 및 기타 태그를 vue 구성 요소의 헤드에 추가할 수 있다.
다음과 같은 간단한 기능:
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 },
// ...
]
}
})
자세한 예는 이 링크를 참조하십시오.
마운트된 태그의 생성에 대한 상위 답변은 좋지만 다음과 같은 문제가 있다.링크를 여러 번 변경하면 태그 만들기가 반복된다.
그래서 이 문제를 해결하기 위해 스크립트를 만들었고, 원한다면 태그를 삭제해도 된다.
그것은 매우 간단하지만, 스스로 그것을 만들 시간을 절약할 수 있다.
// 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>
......
메이지아만뉴엘57의 대답은 훌륭하지만, 내 경우에 효과가 있는 몇 가지 팁을 덧붙이고 싶다(몇 시간 동안 그 팁을 살폈다).우선, 나는 "창" 범위를 사용할 필요가 있었다.또한 "온로드" 함수 내의 Vue 요소에 액세스해야 하는 경우 "이" 인스턴스에 대한 새 변수가 필요하다.
<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에서 작업했다.여기 Javascript에서 "self = this;"라는 속임수가 어떻게 작용하는지에 대한 설명이 있다.
자바스크립트에서 'var that = this;'는 무엇을 의미하는가?
가장 간단한 해결책은 에 스크립트를 추가하는 것이다.index.html
당신의 프로젝트 파일
index.properties:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>vue-webpack</title>
</head>
<body>
<div id="app"></div>
<!-- start Mixpanel --><script type="text/javascript">(function(c,a){if(!a.__SV){var b=window;try{var d,m,j,k=b.location,f=k.hash;d=function(a,b){return(m=a.match(RegExp(b+"=([^&]*)")))?m[1]:null};f&&d(f,"state")&&(j=JSON.parse(decodeURIComponent(d(f,"state"))),"mpeditor"===j.action&&(b.sessionStorage.setItem("_mpcehash",f),history.replaceState(j.desiredHash||"",c.title,k.pathname+k.search)))}catch(n){}var l,h;window.mixpanel=a;a._i=[];a.init=function(b,d,g){function c(b,i){var a=i.split(".");2==a.length&&(b=b[a[0]],i=a[1]);b[i]=function(){b.push([i].concat(Array.prototype.slice.call(arguments,
0)))}}var e=a;"undefined"!==typeof g?e=a[g]=[]:g="mixpanel";e.people=e.people||[];e.toString=function(b){var a="mixpanel";"mixpanel"!==g&&(a+="."+g);b||(a+=" (stub)");return a};e.people.toString=function(){return e.toString(1)+".people (stub)"};l="disable time_event track track_pageview track_links track_forms track_with_groups add_group set_group remove_group register register_once alias unregister identify name_tag set_config reset opt_in_tracking opt_out_tracking has_opted_in_tracking has_opted_out_tracking clear_opt_in_out_tracking people.set people.set_once people.unset people.increment people.append people.union people.track_charge people.clear_charges people.delete_user people.remove".split(" ");
for(h=0;h<l.length;h++)c(e,l[h]);var f="set set_once union unset remove delete".split(" ");e.get_group=function(){function a(c){b[c]=function(){call2_args=arguments;call2=[c].concat(Array.prototype.slice.call(call2_args,0));e.push([d,call2])}}for(var b={},d=["get_group"].concat(Array.prototype.slice.call(arguments,0)),c=0;c<f.length;c++)a(f[c]);return b};a._i.push([b,d,g])};a.__SV=1.2;b=c.createElement("script");b.type="text/javascript";b.async=!0;b.src="undefined"!==typeof MIXPANEL_CUSTOM_LIB_URL?
MIXPANEL_CUSTOM_LIB_URL:"file:"===c.location.protocol&&"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js".match(/^\/\//)?"https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js":"//cdn.mxpnl.com/libs/mixpanel-2-latest.min.js";d=c.getElementsByTagName("script")[0];d.parentNode.insertBefore(b,d)}})(document,window.mixpanel||[]);
mixpanel.init("xyz");
</script><!-- end Mixpanel -->
<script src="/dist/build.js"></script>
</body>
</html>
깨끗한 구성 요소를 유지하려면 혼합물을 사용하십시오.
구성 요소에서 외부 혼합 파일 가져오기
프로필부에를 하다
import externalJs from '@client/mixins/externalJs';
export default{
mounted(){
this.externalJsFiles();
}
}
외부Js.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",
}
}
]
}
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-loader를 사용하여 구성 요소를 자체 파일에서 코드화할 수 있음(단일 파일 구성 요소).이렇게 하면 구성 요소 기준으로 스크립트와 css를 포함할 수 있다.
Vue 3에서는 스크립트 태그가 아직 로드되지 않았는지 확인하기 위해 추가 확인과 함께 mejaamuel57 답변을 사용한다.
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);
}
});
// ...
음, 이것이 치오키안에서의 나의 관습이다.
(이러한 내용은 src/chiokian 파일에서 가져온 것이다.(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)
}
})
},
},
}
이 사용 사례에 대한 vue 구성 요소가 있음
https://github.com/TheDynomike/vue-script-component#usage
<template>
<div>
<VueScriptComponent script='<script type="text/javascript"> alert("Peekaboo!"); </script>'/>
<div>
</template>
<script>
import VueScriptComponent from 'vue-script-component'
export default {
...
components: {
...
VueScriptComponent
}
...
}
</script>
참조URL: https://stackoverflow.com/questions/45047126/how-to-add-external-js-scripts-to-vuejs-components
'Programing' 카테고리의 다른 글
createMemoryHistory는 여전히 브라우저 역사에는 DOM이 필요하다고 보고한다. (0) | 2022.03.25 |
---|---|
왜 람다에서는 인쇄가 안 되는가? (0) | 2022.03.25 |
Vue 라우터 - 경로 간에 쿼리 매개 변수를 전달하는 방법 (0) | 2022.03.25 |
TypeError: rxjs__WEBPACK_Imported_MODUL_2__관측할 수 있다.던지기는 함수가 아니다. (0) | 2022.03.25 |
열별로 NumPy 배열 정렬 (0) | 2022.03.25 |