SONG's 개발새발

4. Vue Component

2019-04-14

Vue 컴포넌트

컴포넌트

  1. 컴포넌트 : 재사용 가능한 html엘리먼트를 캡슐화(부품화)
    1. 유지보수가 쉽다.
    2. 각 컴포넌트들을 첨부해서 사용할 수 있어 재활용성이 높다.
  2. Vue 컴포넌트는 Vue인스턴스 => 모든 옵션 객체 사용 가능
  3. Vue 컴포넌트는 HTML과 독립적이다. (아래 3번 참고)

1. 전역 컴포넌트 등록 : Vue.component( tagName, options )

  • Vue 컴포넌트에 사용자 지정 태그 이름은 케밥케이스로 사용!

  • 컴포넌트가 등록 되면 인스턴스의 템플릿에서 커스텀 엘리먼트로 사용할 수 있다

1
2
3
4
5
6
7
8
9
Vue.component("my-component", {
template: `
<div>인스턴스 템플릿</div>
`
});

new Vue({
el: "#ex"
});
1
2
3
<div id="ex">
<my-component />
</div>

2. 지역 등록 : components

  • 컴포넌트를 components 인스턴스 옵션으로 등록할 수 있다. -> 해당 인스턴스/컴포넌트 범위에서만 사용할 수 있게 만들기 위함.
1
2
3
4
5
6
7
8
9
10
11
var Child = {
template: '<div>사용자 정의 컴포넌트</div>'
}

new Vue({
el: "#ex",
data: {...},
components : {
'my-component' : Child
}
})
1
2
3
<div id="ex">
<my-component />
</div>

3. DOM 템플릿 주의사항

  • DOM을 템플릿으로 사용할 때 (el옵션으로 엘리먼트를 마운트해야 함),
    Vue는 컴포넌트의 template 콘텐츠만 가져올 수 있기 때문에 제한 사항이 있다.
  • ul, ol, table, select와 같은 일부 엘리먼트는 그 안에 li, tr, option등과 같은 꼭 필요한 자식 엘리먼트가 존재하기 때문에 제한을 갖게 된다!
  • 문제점
1
2
3
4
5
> <table>
> <my-component />
> </table>
> // 렌더링시 에러가 발생함!!!
>
  • 해결 방법
  1. is 특수 속성 사용
1
2
3
4
> <table>
> <tr is="my-component" />
> </table>
>
  1. <script type="text/x-templete">
  2. javascript 인라인 템플릿 문자열 가장 선호
  3. .vue 컴포넌트

4. Vue component의 data는 무조건 함수!!

  • Vue 생성자에 사용할 수 있는 대부분의 옵션은 컴포넌트에서 사용할 수 있다. (data, methods, watch …)
1
2
3
4
5
Vue component('my-c',{
data : function(){
return { ... }
}
})

5. Vue.js의 부모-자식 컴포넌트 관계

Vue

Vue component는 HTML DOM과 독립적인 존재이다.

서로 정보공유를 하려면 바인딩을 시켜줘야 한다.

  1. Props 데이터 전달 : 부모가 자식에게 데이터 전달
    • attribute데이터를 가져와서 template 내에 바인딩 될 수 있게 도와준다.
  2. Emit 이벤트 전달 : 자식이 부모에게 이벤트 전달
    • component내에서 발생한 이벤트를 부모에게 전달해 주어 vue인스턴스와 바인딩 된다.

6. Props

1. props 옵션 : 상위 엘리먼트가 하위 컴포넌트로 전달될 수 있다. (위 -> 아래)

1
2
3
4
5
6
Vue.component("child", {
template: `
<span>{{ myMessage }}</span>
`,
props: ["myMessage"]
});
1
<child my-message="바인딩"></child>
1
바인딩
  • html 속성은 대소문자를 구분하지 않는다 ! HTML -> kebab-case(하이픈 구분)
  • Javascript -> camelCased prop

2. 동적 props : v-bind

  • v-bind를 이용해서 부모데이터와 component데이터를 동적으로 바인딩할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Vue.component('modal-open',{

// props를 통해서 부모엘리먼트의 modalShow값을 받았다.(true)
props : ['modalShow'],

// v-if의 modalShow의 값은 true이다!
template : `
<div v-if="modalShow">
</div>
`,
}
})

new Vue({
el : '#ex',
data : {
modalShow : true
}
})
1
2
3
<modal-open
v-bind:modal-show = "modalShow"
></modal-open>

v-bind : modal-show = "modalShow"

  • 부모의 modalShow(true)값컴포넌트의 modalShow가 받게 한다.라는 뜻
  • props:[‘modalShow’] => HTML에서는 modal-show로 표현해 준 것이다.

7. Emit

1. this.$emit : 하위 컴포넌트에서 발생된 이벤트를 상위 엘리먼트에게 전달해준다. (아래 -> 위)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Vue.component('modal-open',{

props : ['modalShow'],

template : `
<div v-if="modalShow">
<button @click="close">이벤트 닫기</button>
</div>
`, // v-on으로 템플릿에 똑같은 방식으로 이벤트를 추가해준다.
},

// this.$emit을 통해 modal-show에게 이벤트가 발생되었다는것을 알려주다.
methods : {
close : function(){
this.$emit('modal-close')
}
}
})

new Vue({
el : '#ex',
data : {
modalShow : true
},
methods : {
// modalClose 함수를 추가한다.
modalClose :function(){
this.modalShow = false
}
}
})
1
2
3
4
<modal-open
v-bind:modal-show = "modalShow"
v-on:modal-close = "modalClose"
></modal-open>

v-on : modal-close = "modalClose"

  • 컴포넌트가 이벤트를 발생시켰다는 것을 modal-close에 알리고 이것을 통해 modalClose이벤트가 발생 한다.라는 뜻
Tags: Vue