본문 바로가기

Frontend Development/Vue.js

[Vue.js] 자식 component height 알아내기, method 호출하기

Vue를 개발할때 가끔 해당 컴포넌트의 <div>의 화면상 높이 값 (clientHeight)이나 자식 컴포넌트의 높이값을 알아야 할때가 있다.

 

그럴때는 vue의 ref 기능을 이용해서 자식 컴포넌트 내부 접근을 할 수 있다. 잠시 ref 사용 예를 알아보면 다음과 같다. 접근을 원하는 component나 html element에 ref="링크명"을 붙여주고 this.$refs.xxxx 로 접근을 하면 된다.

 

ref 사용예시

<template lang="html">
  <div>
    <div class="layout__background" @click="disableSideElement">
      <div class="header__background"></div>
      <div class="content__background"></div>
      <div class="footer__background" style="top: 649px;"></div>
    </div>
    <div class="layout__main">
      <Header ref="headerRef" /> => 접근울 원하는 component에 ref변수를 붙여준다.
      <Contents :height="this.contentHeight" />
      <Footer ref="footerRef" />
    </div>
  </div>
</template>
handleResize(event) {

  // this.refs 변수를 살펴보면 위에서 지정한 ref 링크가 적제되어 있고 component의 경우 $el 변수가 적재된다.
  this.contentHeight = window.innerHeight - this.$refs.headerRef.$el.clientHeight - this.$refs.footerRef.$el.clientHeight;
},

 

그러나 아무시점에서나 this.$refs.xxxx로 접근하면 원하는 링크가 메모리에 적재가 안되어 있어 undefined 에러를 만나게 된다. 이를 위해서는 Vue의 기본적인 lifecycle을 알고 가는게 중요하다.

 

Vue life Cycle

그림이 거창하지만 vm.$el이 생기는 지점 즉 mounted 이후에 접근을 하면 대부분 링크 사용이 가능해진다. Vue에서 mounted() {} api내에서 사용하면 된다는 것이다.

 

위 예제에서 application 동작중에 아래는 mounted() method내에서 handleResize를 부른 모습이다. mounted가 완료되어서 this.$refs에 하위 컴포넌트 링크 'footerRef', 'headerRef'가 변수에 들어가 있고 headerRef의 $el 변수의 clientHeight 값을 읽어오면 해당 컴포넌트의 현재 div 높이를 알수 있게 된다.

 

 

컴포넌트 외에 html 기본 element 에서 ref 사용

 

위와 같이 vue component외에도 기본 html element에도 ref를 달아서 사용할수 있다. 단 이때에는 vue의 컴포넌트 지시자 $el이 생성되지 않고 바로 attribute에 접근 하면 된다

 

<template>
  <div class="card">
    <div class="img-wrapper" ref="imgWrapperRef">
      <transition name="fade">
        <img class="card-img-top" :src="video.snippet.thumbnails.high.url" @load="onImgLoad" v-show="this.loaded" />
      </transition>
    </div>
  </div>
</template>

<script>
  import {mapActions} from 'vuex';

  export default {
    name: 'VideoItem',
    props: {
      video: Object
    },
    data() {
      return {
        loaded: false
      };
    },

... 중략

    computed: {},
    methods: {
      onImgLoad(ele) {
        this.loaded = true;
      },
      getHeight() {
      	// this.$refs.imgWrapperRef.$el.clientHeight 이 아니고 this.$refs.imgWrapperRef.clientHeight 로 
        // 바로 clientHeight 접근한다.
        return this.$refs.imgWrapperRef.clientHeight;
      }
    }
  };
</script>

 

ref를 이용한 하위 컴포넌트 method 직접 호출

 

머 당연한 이야기겠지만 위 $refs 변수를 통해서 하위 element의 methodeh 직접 호출하면 된다.

즉 호출하려는 부모 component에서 this.$refs.refrencename.getHeight() ... 등으로 reference 명 다음에 해당 컴포넌트의 함수를 호출해주면 하위 컴포넌트의 상태나 기타 정보를 get하는데 사용할 수 있다.

 

단상...

 

그러나 먼가 링크를 만들어서 자식의 내부 상태 object를 직접 접근하는 방식은 깔끔해 보이진 않는다. 객체 지향 원리에 맞는지도 모르겠고 스파게티가 될 가능성도 있어보인다. Vue에서도 자식의 상태를 위해서는 props, event api들을 이용해서 명시적이고 공식적인 방법을 주로 사용하고 정... 급할경우(?)에 ref를 사용하라고 가이드하고 있다.

 

자식의 상태를 받을수 있는 event들은 다음 링크에서 확인가능하다.

https://v2.vuejs.org/v2/api/?redirect=true#Instance-Methods-Events 

 

-- The End --