Front-End

[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');
    },

 

[연관 정보]

 

Leave a Reply

error: Content is protected !!