vue 프레임 워크를 사용해서 프로젝트를 진행하다 보니, api 연동 등으로 인해 vue 파일 내 스크립트 코드가 아니라 .js 파일을 작성해서 개발을 진행해야 하는 경우가 생겼는데, js 파일 내 함수에서 해야 할 작업을 완료 한 이후에 vue 파일(현재 보이는 화면)의 함수를 호출해야 했음.
아니 근데 세상에 js파일은 굳이 따지면 vue 프레임워크 외부의 파일이다 보니 this 로도 접근이 안되고 어떻게 접근 방법이 없어서 어찌어찌 맨땅에 헤딩 하다가 찾은 외부 js 파일에서 vue 함수 호출하는 방법. 서두는 여기까지 하고 아래부터 적용하는 방법.
+) 2021.06.09 추가
plugin을 활용해서 더 간결하고 안정적으로 처리하는 방법을 찾음! 링크는 게시글 하단에 링크 달아뒀으니 필요하다면 참고바람. 단, 이 포스팅 원리(?) 를 기반으로 두고 있으니 읽고 가는것도 좋습니다.
[main.js]
window.app = vm; 코드 추가
[index.html]
<body>
hljs.initHighlightingOnLoad();
<noscript><strong>Error Msg</strong></noscript>
<div id="app"></div>
<script src="(.js 파일명 또는 파일위치경로)" language="javascript" type="text/javascript"></script>
</body>
*스크립트 코드는 <div id="app"></div>, vue component가 호출된 후 import할 것
∵ jquery에서 vue component 함수를 호출할 때 vue component가 로드되지 않은 상태에서는 error발생
[import 한 js 파일 내부]
var vm = window.app;
function sampleFunction(value) {
// vm.$root.$children[0].$refs.(설정한 vue ref값) + 호출하고자 하는 함수명
vm.$root.$children[0].$refs.componentRef.sample();
}
* 변수로 등록한 window.app vue root인 vm을 사용해 component의 함수를 호출한다.
콘솔로 vm 또는 window.app 을 찍어보면 페이지 구조를 뒤져볼 수 있는데 $refs 부터 children 값들을 하나하나 뒤져보면 vue 파일에서 지정한 함수나 변수가 등록된 걸 확인할 수 있음.
만약 호출해야 하는 페이지가 단일 페이지가 아니라 페이지 내에서 import해서 사용하는 components 나 페이지라면 다시 경로를 추적해서 위쪽 코드에 적용해줘야 함.
예를들어 아래와 같은 구조의 페이지가 있을 때
js내 함수가 호출 된 후에 sample() 이라는 함수를 호출하고 싶다면 js 파일 내의 호출 코드는 아래와 같이 해야한다는거
vm.$root.children[0].$refs.componentRef.children[0].children[2].sample();
+) 2020.10.22 추가
어쩌다가 다시 이쪽을 수정 할 일이 있어서 확인했는데 $root 는 생략이 가능한 듯.
그리고 이게 위치를 자동 추적하는게 아니라 하드코딩으로 경로를 코딩하는 방식이다 보니 페이지 내 구조가 바뀌거나 components가 추가/삭제 됨에 따라 children 값의 index 가 달라지면서 정상적으로 동작하지 않는 경우가 발생함.
-> 이런 현상 해결을 위해 전역 mixin 을 활용하는 방법도 찾아서 기록해뒀던데 이것도 개인적으로 뒤지다가 발견한거라 썩 깔끔하고 훌륭한 방법은 아닌 듯 하다.. 우선 링크는 게시글 하단에 박아뒀음.
[App.vue]
<template>
<div id="app">
<router-view ref="componentRef"></router-view>
</div>
</template>
<script>
import Vue from 'vue'
export default {
name: 'app'
}
</script>
*개발 페이지 Vue component들은 App.vue (root파일) 내의 <router-view/> 안에서 변경된다.
현재 다른 하위 컴포넌트 없이 router에 바로 기능동작 컴포넌트를 깔아놨으므로 root에 ref값을 정해준 것.
호출할 함수는 component에 작성한다.
[example.vue] _component
<script>
export default {
name: 'example',
methods: {
sample() {
// js파일에서 호출한 function
}
},
mounted() {
let jsScript = document.createElement('script');
jsScript.setAttribute('src',"js파일경로");
document.head.appendChild(jsScript);
},
};
</script>
*ref를 선언한 vue파일이 아닌 실제 기능처리가 이루어질 component파일의 mathods내에 함수를 선언한다.
script파일의 경우 root에 등록해도 상관 없지만 그렇게 하면 모든 페이지에 적용된다.
나는 특정 페이지에 진입했을 경우에만 해당 js파일이 적용되길 원해서 해당하는 페이지의 vue 파일 내 mounted에 등록했음.
등록 함수도 created, mounted ... 크게 상관은 없는 듯 하다. vue 라이프 사이클 확인해서 document 객체가 사용 가능한 위치에서 프로그램 구조 상 적절하다고 판단되는 곳에 작성하면 될 것 같음.
추가로 vue에서 js함수를 호출할 때에는 index.html에서 js파일을 import 해놨다면 'this.함수명()' 처럼 this객체를 사용할 필요 없이 함수 내에서 '함수명()' 으로 바로 호출이 가능하다.
this 객체 자체가 export 하는 자신을 의미하는데, index.html 에 등록하면 전역으로 활성되기 때문인 듯.
+추가 (20.03.11)
프로젝트마다 component 경로가 다르고, 구조별로 $ref.. 등으로 호출이 안되는 경우도 발생해서 전역 mixin을 사용하는 방법을 시도해봤는데, 프로그램이 깔끔하다고는 못 하겠으나 일단 동작은 하는 것 같다. 일단 이번에도 메모/기록용으로 포스팅 추가해놨음
++추가 2021.06.09
위에 작성한 것과 같은 이슈로 고민하다가 시간이 많이 흘렀는데, 현재로서는 꽤 만족스러운 방법을 찾아서 포스팅 해뒀다. 2번 글에서 처럼 mixin을 사용하면 다른 이슈가 발생하는데, 이번에 plugin을 활용해서 처리하니 깔끔하고 간결해짐 굳굳
'Client > Vue' 카테고리의 다른 글
[vue] vue moment, moment.js (0) | 2019.05.31 |
---|---|
[vue] event.preventDefault() (0) | 2019.05.27 |
[vue] 우정국 api를 활용한 주소찾기 (0) | 2019.05.17 |
[vue] jsonp 데이터 & xml to json (0) | 2019.05.17 |
[vue][Issue] daumPost redirect 이슈 (0) | 2019.05.16 |