[vue.js]콤포넌트(component)로 구성된 TAB 페이지에서 지역 콤포넌트 뷰의 함수를 호출하는 방법($refs)
뷰 화면이 여러개의 콤포넌트로 구성된 화면이 있다.
이 뷰는 탭을 사용중이며 탭을 클릭할 때 마다
해당 지역 콤포넌트(Local component)를 import해서
뷰를 호출하는 구조이다.
콤포넌트를 사용하는 이유는 재사용성이 가능 클 것이다.
저장하는 버튼이 Detail.vue 의 탭에 존재하고 있다면
콤포넌트 뷰(Memo.vue)의 내부에 saveComplete() 저장 함수를
어떻게 호출할 수 있을까?
Refs를 사용하면 쉽게 처리할 수 있습니다.
자바스크립트에서 DOM과 엘리먼트 등에 접근하기 위해서는
getElementById, getElementByClassName 등의 메소드를 사용해야하지만
Vue.js에서는 Refs를 제공해줌으로써 쉽게 접근할 수 있습니다.
Detail.vue의 일부 코드는 다음과 같다.
[Detail.vue]
<!--상단탭-->
<v-tabs
class="ubs-tabs relative"
grow
background-color="white"
color="cyan darken-1"
>
<v-tab :key=i
v-for="(item, i) in tabs"
v-show="item.enable === 'Y'"
@click="movePage(item.id)">{{item.name}}</v-tab>
</v-tabs>
<keep-alive>
<component :is="currView" ref="eventCall"
@returnStatus="returnStatus"
:userId="pUserId"
:companyId="pComapnyId">
</component>
</keep-alive>
..........이하 생략...........
<script>
import Report from '@/views/components/Report.vue';
import Memo from '@/views/components/Memo.vue';
import Feedback from '@/views/components/Feedback.vue';
export default {
name: '상세정보',
components: {
Report,
Memo,
Feedback,
},
data: () => ({
currView: 'Report',
currDate: moment(new Date()).format('YYYY-MM-DD'),
tabs: [
{ id: 'Report', name: '보고서', enable: 'Y' },
{ id: 'Memo', name: '메모', enable: 'N' },
{ id: 'Feedback', name: '피드백', enable: 'N' },
],
codeList: {
actStatusList: [],
},
option: {},
isMailDialog: false,
}),
.........이하 생략...........
methods: {
saveData() {
this.$refs.eventCall.saveComplete();
},
returnStatus() {
this.completeStatus = false;
},
},
콤퍼넌트 뷰 (Memo.vue)
<template>
<v-container>
<v-layout row wrap style="border-bottom:none;">
<v-flex>
<div>
</div>
</v-flex>
</v-layout>
<div v-if="page.totCnt !== memoList.length"
class="text-center mb14"
@click="morePage();">
<v-btn class="ubs-btn-more-round" rounded outlined color="#222">
더보기 +
</v-btn>
</div>
<!--플로팅 버튼-->
<v-btn
class=""
bottom
color="#222222"
dark
fab
fixed
right
@click="memoDetail()"
>
<v-icon>mdi-plus</v-icon>
</v-btn>
<AlertDialog :parentData="alertData" />
<ConfirmDialog :parentData="confirmData" />
</v-container>
</template>
<script>
export default {
name: 'Memo',
props: {
userId: { type: String },
companyId: { type: String },
},
data: () => ({
page: {
totCnt: 0, // 리스트 전체 갯수
rowPerPage: 10, // 최초 가지고 올 데이터 갯수
currPage: 1, // 현재 페이지
},
data: {
guideId: '',
},
}),
created() {
},
mounted() {
this.searchMemo();
},
methods: {
morePage() {
this.page.currPage += 1;
this.searchCallMemo('MORE');
},
saveComplete() {
this.saveMemo();
},
callTabEvent() {
this.$emit('returnStatus');
},
},
};
</script>
$refs 속성 사용방법
Detail.vue에서 콤포넌트를 호출하는 부분에서 ref 속성을 주어서 접근할 수 있다.
ref속성값은 가독성을 위해 문자열값으로 지정한다.
<component :is="currView" ref="eventCall"
......생략>
</component>
그런 다음
Memo 뷰의 saveComplete()함수를 호출하기위해 아래와 같은 형식으로 호출하여 접근할 수 있다.
saveData() {
this.$refs.eventCall.saveComplete();
},
refs 사용시 주의사항
$refs는 컴포넌트가 렌더링 된 후에 존재하게 됩니다. 해당 속성은 자식 요소에 직접 접근하기 위해서만 사용되어야 합니다. 즉, 템플릿이나 computed 속성에서 $refs에 접근해서는 안됩니다. |
$emit 사용방법
반대로 콤포넌트뷰인 Memo.vue에서 Detail.vue에 존재하는 returnSatatus 함수를 호출하는 방법은 다음과 같다.
Detail.vue에서 콤포넌트 뷰를 설정할 때 @retrunStatus라는 임의의 호출변수를 선언하고 그의 값으로 호출될 함수를 문자열값으로 지정해준다.
<component :is="currView"
@returnStatus="returnStatus">
</component>
그리고
Memo.vue에서 $emit 함수를 이용하여 Detail.vue에서 임의로 지정했던 호출 변수를 호출해주면 된다.
callTabEvent() {
this.$emit('returnStatus');
},
[연관 정보]
- https://codingexplained.com/coding/front-end/vue-js/accessing-dom-refs
- https://v3.ko.vuejs.org/guide/component-template-refs.html