[Vue.js] 02 Component

2021. 9. 23. 14:07Study/Vue.js

반응형

컴포넌트

  • Vue.js가 제공하는 가장 강력한 기능 중 하나
  • 컴포넌트는 HTML 마크업, 자바스크립트 로직을 포함한 하나의 덩어리
  • 캡슐화가 자연스럽게 가능해지고 따라서 재사용이 가능해짐

 

전역 컴포넌트 선언

  • Vue.component는 컴포넌트를 글로벌하게 등록하는 메서드
  • 주의 : 확장된 Vue인스턴스, 즉 컴포넌트에서 data를 정의할때 반드시 함수로 정의해야함
  • Tip: 컴포넌트 이름을 하이픈을 포함한 소문자여야 함
Vue.component('컴포넌트 이름', 컴포넌트 내용); 

Vue.component('app-header', {     
	template: '<h1>Header</h1>' 
}); 

Vue.component('app-content', {     
	template: '<div>content</div>' 
});

 

지역 컴포넌트 선언

  • 컴포넌트를 Vue인스턴스 혹은 컴포넌트의 옵션으로 등록해 해당 컴포넌트 내부에서만 사용하도록 지정
new Vue({
  el: '#app',
  components: {    // key : value 형식
    'app-footer': {
        template: '<footer>footer</footer>'
     }
  }
});

혹은

var appFooter = {
    template: '<footer>footer</footer>'
};

new Vue({
  el: '#app',
  components: {    // key : value 형식
    'app-footer': appFooter
  }
});

 

제한사항

  • ul, ol, table, select와 같은 일부 엘리먼트 내부에서는 컴포넌트를 사용할 수 없습니다.
  • 제한 있는 엘리먼트 내부에 컴포넌트를 사용할 경우 문제 발생 > is 옵션을 사용해 정상적으로 렌더링 할 수 있음

 

컴포넌트 통신방식

  • 부모 컴포넌트가 자식 컴포넌트에게 데이터를 전달하는 것이 가능
  • 자식 컴포넌트는 부모 컴포넌트에게 데이터를 전달하는 것은 불가능
  • 자식 컴포넌트가 부모 컴포넌트에게 이벤트를 전달해 부모 컴포넌트에게 메시지를 전달 가능

뷰 컴포넌트는 각각 고유한 데이터 유효 범위를 갖는다. 따라서, 컴포넌트 간에 데이터를 주고 받기 위해선 아래와 같은 규칙을 따라야한다.

  • 상위에서 하위로는 데이터를 내려줌, props 전달
  • 하위에서 상위로는 이벤트를 올려줌, event 발생
  • 부모는 props를 통해 자식에게 데이터를 전달하고 자식은 events를 통해 부모에게 메시지를 보

 

Props

데이터 전달

  • 모든 컴포넌트 인스턴스에는 자체 격리 된 범위 가 있다.
  • 하위 컴포넌트의 템플릿에서 상위 데이터를 직접 참조할 수 없다.
  • 데이터는 props 옵션을 사용하여 하위 컴포넌트로 전달하여야 한다.
  • 하위 컴포넌트는 props 옵션을 사용하여 수신 할 것으로 기대되는 props를 명시적으로 선언해야한다.
Vue.component('child', {
 // props 정의
 props: ['myMessage'],
 // 데이터와 마찬가지로 prop은 템플릿 내부에서 사용할 수 있으며
 // vm의 this.message로 사용할 수 있습니다.
 template: '<span>{{ message }}</span>'
})
  • HTML 속성은 대소 문자를 구분하지 않으므로 문자열이 아닌 템플릿을 사용할 때 camelCased prop 이름에 해당하는 kebab-case(하이픈 구분)를 사용해야 한다.
<child v-bind:my-message="안녕하세요!"></child>

 

동적 props

  • 정적 props : String 타입 외에 Number, Object, List 데이터는 전달할 수 없음. 또한 전달된 데이터는변경할 수 없음
  • 동적으로 데이터를 전달하고 싶다면 v-bind를 이용해 데이터를 전달
  • 부모 컴포넌트의 message가 변경된 경우 자식 컴포넌트는 다시 message 데이터를 받아 다시 렌더링

 

Event emit

  • 자식 컴포넌트는 부모 컴포넌트에게 데이터를 전달할 수는 없지만 이벤트를 통해 메시지를 전달할 수 있음
  • 자식 컴포넌트는 $emit을 이용해 이벤트를 실행
  • Vue 인터페이스는 다음과 같은 이벤트 인터페이스를 구현
    • $on(eventName)을 사용하여 이벤트를 감지
    • $emit(eventName)을 사용하여 이벤트를 트리거 
<div id="app">
  <app-header v-on:pass="logText"></app-header>
  <app-content v-on:increase="increaseNum" v-bind:props-num="num"></app-content>
</div>
...
<script>
  var appHeader = {
    template: '<button v-on:click="passEvent">Click me</button>',
    methods: {
        passEvent: function () {
            this.$emit('pass');
        }
    }
  }

  var appContent = {
    template: '<button v-on:click="addNumber">Add {{propsNum}}</button>',
    props: ['propsNum'],
    methods: {
        addNumber: function() {
        this.$emit('increase')
      }
    }
  }

  new Vue({
    el: "#app",
    components: {
      'app-header': appHeader,
      'app-content': appContent
    },
    data: {
      num: 10
    },
    methods: {
        logText: function () {
        console.log("click!!");
      },
      increaseNum: function() {
        this.num++;
      }
    }
  });
</script>




같은 레벨 컴포넌트 간의 통신

  • 같은 레벨 컴포넌트 간에는 직접적인 데이터 전달이 불가능하다.
  • 상위 컴포넌트로 이벤트 전달 후, 상위 컴포넌트에서 다른 하위 컴포넌트로 데이터를 전달해준다.

 

 

<div id="app">
  <app-header v-bind:props-num="num"></app-header>
  <app-content v-on:pass="deliverNum"></app-content>
</div>


<script>

  let appHeader = {
    template: '<div>header-{{ propsNum }}</div>',
    props: ['propsNum']
  }

  let appContent = {
    template: '<div>Content<button v-on:click="passNum">pass</button></div>',
    methods: {
        'passNum': function () {
            this.$emit('pass', 10);
         }
    }
  }

  new Vue({
    el: "#app",
    components: {
      'app-header': appHeader,
      'app-content': appContent
    },
    data: {
      num: 0
    },
    methods: {
        deliverNum: function(value) {
            console.log(value);
            this.num = value;
        }
    }
  });
</script>

 

 

출처 : https://www.inflearn.com/course/Age-of-Vuejs

반응형

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

[Vue.js] 09 ES6  (0) 2021.09.24
[Vue.js] 07 SFC(Single File Component)  (0) 2021.09.24
[Vue.js] 05 Template  (0) 2021.09.23
[Vue.js] 03 Router  (0) 2021.09.23
[Vue.js] 01 Instance  (0) 2021.09.23