본문으로 바로가기

[Vue.js] 컴포넌트

category Web/Vue.js 2019. 12. 4. 16:23

1. 컴포넌트란?

Vue.js에서 컴포넌트는 코드 베이스를 줄이고 단순화하는 강력한 구성 요소

어떻게 Vue.js 컴포넌트를 생성하느냐에 따라 Vue.js의 개발속도와 코드의 가독성, 그리고 효율성이 현저히 차이남

 

코드에서 반복되는 부분을 가져와 이해하기 쉬운 작은 논리적 부분으로 분리

(쉽게 말해, 화면을 구성할 수 있는 블록이라고 생각할 수 있을 것 같다.)

애플리케이션 내에서 재사용 가능하며 코드를 이해하기 쉽다는게 장점이다.

 

2. 컴포넌트 등록

컴포넌트 등록은 '전역 등록'과 '지역 등록'으로 나눌 수 있다.

 

1) 전역  등록

컴포넌트 전역등록은 프로그래밍에서 전역 변수와 같은 의미이다.

인스턴스 생성 후 어느 페이지 또는 컴포넌트에서 사용할 수 있게 Global 하게 등록할 수 있다.

 

<예시 - global-component-example.html>

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
    <my-component></my-component>
  </div>
  <script>
  Vue.component('my-component', {
    template: '<div>안녕, 전역 컴포넌트로부터</div>'
  });
  new Vue({
    el: "#app"
  });
  </script>
</body>
</html>

2) 지역 등록

지역 등록은 Vue 인스턴스 하나로 범위를 제한

컴포넌트의 인스턴스 옵션과 함께할 수 있으며 등록한 Vue 인스턴스만 해당 컴포넌트에 접근할 수 있음

<예시 - local-component-example.html>

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
    <my-component></my-component>
  </div>
  <script>
    const Component = {
      template: '<div>안녕, 지역 컴포넌트로부터</div>'
    }
    new Vue({
      el: '#app',
      components: {'myComponent': Component}
    });
  </script>
</body>
</html>

3. 컴포넌트의 관계

컴포넌트는 부모-자식 관계를 가짐, 각 컴포넌트는 분리된 범위가 있기 때문에 부모 데이터에 직접 접근할 수 없음

따라서 항상 데이터를 전달하게 됨! 이때 부모에서 자식으로 전달된 데이터를 props라고 함

컴포넌트는 단방향 데이터 바인딩을 형성 (-> 속성이 부모에서 자식으로는 흘러가지만 반대로는 안됨)

 

4. 속성을 사용한 데이터 전달

1) 동적 속성

정적인 문자(리터럴 속성)과 다르게 변경될 수 있는 속성을 가지고 있는 부모에게서 전달받은 속성

v-bind 지시자를 사용, 올바르게 전달 되었는지 확인 가능

<예시 - dynamic-props.html>

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
    <my-component v-bind:text="message"></my-component>
  </div>
  <script>
  const MyComponent= {
    template:`<div>안녕 {{text}}! </div>`,
    props:['text'],
    created() {
        this.text = this.text +' 1';
    }
  };
  new Vue({
    el: "#app",
    components: {'my-component': MyComponent},
    data() {
      return {
        message: '부모 컴포넌트로부터!'
      }
    }
  });
  </script>
</body>
</html>

2) 속성 검증

부모에게 받은 속성의 유효성 여부를 검증하는 속성 검증 기능이 있음

문자열, 숫자, 불, 함수, 객체, 배열, 기호에 대한 순수 생성자를 제공함

<속성체크예시>

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
    <my-component :num="myNumber" :str="passedString"
                  :obj="passedObject"></my-component>
  </div>
  <script>
  const MyComponent={
    template:'<div>숫자: {{num}}<br />문자열: {{str}} \
              <br/>객체:{{obj.message}}</div>',
    props:{
      num: {
        type: Number,
        required: true
      },
      str: {
        type: String,
        default: "안녕"
      },
      obj: {
        type: Object,
        default: ()=> {
          return {message: '안녕, 객체로부터'}
        }
      }
    }
  }
  new Vue({
    el: '#app',
    components:{'my-component':MyComponent},
    data() {
      return {
        passedString: '안녕, 부모로부터!',
        myNumber: 43,
        passedObject: {message: '넘겨준 객체'}
      }
    }
  });
  </script>
</body>
</html>

- default 기본값은 속성에 아무 값도 전달되지 않았을 때의 값을 의미

- 속성타입이 객체라면 반드시 기본값이 할당되어야 함

- 단일 콜론(:)은 v-bind의 약자

 

5. 커스텀 이벤트

일반적인 이벤트와 다르게 부모에서 자식 컴포넌트로 이벤트를 넘겨줄 때 사용

$on(event)을 사용하여 이벤트를 수신, $emit(event)을 사용하여 트리거

$emit(event)을 사용해 부모컴포넌트에 정보 전달이 가능

 

<이벤트 수신 예시>

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
    {{counter}}<br/>
    <button v-on:click="incrementCounter">카운터 증가</button>
    <my-component v-on:increment-me="incrementCounter" ></my-component>
  </div>
  <script>
  const MyComponent = {
    template: `<div>
      <button v-on:click="childIncrementCounter">자식으로부터 증가</button>
    </div>`,
    methods: {
      childIncrementCounter() {
        this.$emit('increment-me');
      }
    }
  }
  new Vue({
    el: '#app',
    data() {
        return {
            counter: 0
        }
    },
    methods: {
      incrementCounter() {
        this.counter++;
      }
    },
    components: {'my-component': MyComponent}
  });
  </script>
</body>
</html>

위의 코드를 보면 This.$emit('increment-me')를 사용해서 부모 메서드에서 정의한 incrementCounter 이벤트를 호출해 카운터를 증가시키게 되어 있음. 이렇게하면 단방향 데이터 규칙을 지키면서 부모 값 변경이 가능함

 

참고 사이트

- [Vue.JS] Component 개념을 익히고 만들어보자!! https://kdydesign.github.io/2019/04/27/vue-component/

- [Vue.js] 뷰 컴포넌트 http://cigiko.cafe24.com/vue-js-%EB%B7%B0-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8/

- Vue.js 코딩 공작소 _ 길벗출판사예제 https://github.com/gilbutITbook/007024


컴포넌트를 생성하는 것은 쉽게 따라할 수 있겠지만

어떻게 구성할지 설계가 굉장히 중요할 것 같음  어렵다~😢

포스팅에 작성한 예시들은 개념에 대한 이해를 돕기 위한 것들이고

 

보통 컴포넌트의 작성은 Template Script 그리고 Style Sheet를 하나의 파일에 작성하는

단일 파일 컴포넌트(Single File Component)로 작성한다!

'Web > Vue.js' 카테고리의 다른 글

Vue-CLI 파이어베이스 배포하기  (0) 2019.12.26
Vue-CLI 프로젝트 만들기  (0) 2019.12.05
[Vue.js] 라이프사이클  (0) 2019.12.01
"Vue.js 코딩 공작소" 학습 후기  (0) 2019.11.09
MVVM패턴이란?  (0) 2019.11.09