컴포넌트 생성

– 컴포넌트 생성방법 알기

– 부모가 자식 컴포넌트를 가지는 방법 알기

 

root 컴포넌트에 있는 부분을 voter 라는 새로운 컴포넌트를 만들고 이동한다.

컴포넌트의 구성요소는 뷰를 담당하는 template와 모델 영역인 data + methods로 구성된다.

그리고 root 컴포넌트에서 이 voter 컴포넌트를 <voter></voter>로 가지게 된다.

이와같이 컴포넌트는 트리형태를 가지게 된다.

 

실행을 해보면 두가지의 에러가 생기게 된다.

vue.js:597 [Vue warn]: The “data” option should be a function that returns a per-instance value in component definitions.
vue.js:597 [Vue warn]: Error compiling template:

<h2>{{name}}: {{ result }}</h2>
<button @click=”agree”>Agree</button>
<button @click=”disagree”>DisAgree</button>

– Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.

data는 funcion이여야 한다는것이고 template는 하나의 root element를 가져야 한다는것이다.

 

부모 자식간의 기본적인 통신 방법

실제 개발을 하다보면 모든 데이터는 root 혹은 부모가 데이터를 갖고 있는게 로직처리를 하는게 더 쉬워진다.

예)  틱택톡 게임

9칸으로 구성된 틱택토 게임은 한칸을 자식 컴포넌트로 구성하고 자식 컴포넌트가 가질수 잇는 속성은 O, X 두가지라고 했을때

자식 컴포넌트로 부터 9개의 인스턴스를 구성하고 클릭시 이벤트를 발생하여 O, X를 가지게 한다고 가정해보자.

실제로 게임 로직은 O 혹은 X로 구성된 부분이 가로, 세로, 대각선을 만들었는지를 체크해야만 한다. 그런데 이 값을 자식 컴포넌트가 갖고 있으므로 이 값이 바뀔때마다 부모 컴포넌트에게 알려줘야 한다.

이렇게 할 바에야 차라리 이 값을 처음부터 부모가 갖고 있다가 자식한테 알려주는 방법이 더 효율적이다.

부모가 자식에게 모델 데이터 값을 보내 주는 방법은 v-bind:자식변수=”부모변수” 이다.

자식이 이 변수를 받는 방법은 props로 받게 된다.

위에 name과 result 모델을 이렇게 정의해보자.

먼저 부모 컴포넌트에게 name과 result 데이터값을 정의한다.

그리고 자식 컴포넌트에서는 이 값을 물려받도록 한다.

 

그리고 agree, disagree 버튼을 눌러보자.

잘 동작하는것처럼 보이지만 콘솔창을 보면 다음과 같은 에러가 보인다.

vue.js:597 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “result”

found in

—> <Voter>
<Root>

props 데이터를 직접 변경하는것을 피하라. 왜냐하면 부모 컴포넌트가 다시 렌더링 될때마다 오버라이트 될것이다.

부모가 result 값을 변경하면 그 값이 부모도 바뀌고 자식도 바뀌지만 자식이 이 값을 바꾸면 바뀐 값이 부모에게는 전달이 안된다는 의미이다.

즉, 단방향 데이터 흐름이다.

부모컴포넌트에 result를 바인딩해서 테스트해보거나 크롬 devtools를 통해서 확인해보자.

크롬 devtools 는 확장팩으로 추가해서 사용할 수 있다.

 

그래서, result 값을 변경하고 싶으면 자식이 부모에게 바꿔달라고 요청을 해야 한다.

 

 

 

 

 

 

 

 

 

모든 Vue 인스턴스는 다음과 같은 이벤트 인터페이스를 구현한다.

$on(eventName)을 사용하여 이벤트를 감지
$emit(eventName)을 사용하여 이벤트를 트리거(발생)

하지만, 하나의 예외가 있는데 $on 일 경우에는 자식 컴포넌트의 이벤트를 감지 하지 못한다. 그래서 v-on으로 바인딩해야 한다.

먼저 부모 컴포넌트에 두개의 이벤트를 추가한다.

v-on으로 on-agree, on-disagree 이벤트를 감시하고 있다가 해당 이벤트가 발생하면 handleAgree, handleDisagree 메서드를 호출하라는 의미이다.

 

자식 컴포넌트에서는 클릭이벤트가 발생했을때 on-agree, on-disagree 이벤트를 emit 한다.

devtools에서 제대로 이벤트가 발생하는지 확인하자.

 

전체 소스는 다음과 같다.