초보 개발자

Vue 기초2 본문

vue.js

Vue 기초2

taehyeki 2022. 4. 1. 11:38

클래스 바인딩

Vue에서 클래스 바인딩 하는 것을 알아보자!!

먼저 red라는 클래스에 컬러를 red로 지정해두고, p태그를 보면 class를 괄호로 감싼뒤 red(클래스명) : isRed로 

key value형식으로 만들어 둔 것을 확인할 수 있다. isRed의 값이 true, false에 따라서 red라는 클래스가 적용이 될 수도, 안 될 수도 있다. false라면 적용이 안되고, true라면 적용이 된다. 따라서 버튼을 클릭하면 isRed값을 반대로 바꿔줌으로써 클래스를 적용할 수 있다.

버튼을 클릭 하면 아래와 같이 바뀐다,

클래스를 여러개 사용하고 싶다면 class="{ red : isRed, bold : isBold }"이렇게 오브젝트 형식으로 늘려나가면 된다. 이 때에 bold라는 클래스를 사전에 만들어 두어야 사용이 가능하다.

 

만약 클래스 이름 사이에 대쉬가 들어있다면 예를들어 font-bold 처럼

이 경우에는 class="{ 'font-bold' : isBold } 이렇게 작은 따옴표로 감싸주면 된다.

 

false true의 유무에 관계없는 클래스를 기본적으로 두고 싶은 경우에는 class를 옆에 만들어 둔 뒤 평소처럼 사용하면 된다.

 

데이터 안에 obj를 만든 뒤에 class에 통째로 적어줘도 상관없다.

 

전역 컴포넌트 지역 컴포넌트

 

Vue.component로 만든 것이 전역 컴포넌트이고, Vue 인스턴스 안에 만든 component는 로컬 컴포넌트이다.

얼핏 보았을 때는 비슷해보인다.

이 두개의 차이는 무엇일까? 차이점을 확인하기 위해 Vue인스턴스를 하나 더 생성해보자!

 

두 번째 인스턴스에서는 전역 컴포넌트를 불러올 수 있지만 지역 컴포넌트를 불러올 수 없다.

이는 전역 컴포넌트와 지역 컴포넌트의 유효범위가 다르기 때문이다.

첫 째 인스턴스의 유효범위는 첫 번째 인스턴스 영역으로 제한 되기에 <div id='app'>에 등록했어도 <div id='app2'>의 범위 안에서는 지역 컴포넌트가 인식이 되지 않는다.

 

지역 컴포넌트는 해당 인스턴스에서 정의한 컴포넌트만 불러올 수 있는 것이고(인스턴스를 등록할 때마다 만들어 주어야 함), 전역 컴포넌트는 한 번 등록해두면 어느 인스턴스이던 다 불러올 수 있다는 것(한 번만 만들어 주면 됨)이 차이점이다. 

 

컴포넌트 간 통신 및 유효범위

컴포넌트는 각각 고유한 유효 범위를 갖고 있기 때문에 직접 다른 컴포넌트의 값을 참조할 수 없다.

따라서 뷰 프레임워크 자체에서 정의한 컴포넌트 데이터 전달 방법을 따라야 한다.

 

가장 기본적인 데이터 전달 방법은 바로 상위(부모) - 하위(자식) 컴포넌트 간의 데이터 전달 방법입니다.

 

상위 - 하위 컴포넌트란 트리 구조에서 부모 노드, 자식 노드처럼 컴포넌트 간의 관계가 부모, 자식으로 이루어진 컴포넌트를 의미한다.

 

위에서 전역 컴포넌트와, 지역 컴포넌트를 등록했을 때를 살펴보자,

이 때 등록된 컴포넌트는 자연스럽게 하위 컴포넌트가 되고, 그리고 하위컴포넌트를 등록한 인스턴스는 상위 컴포넌트가 된다.

 

먼저 상위에서 하위로는 props라는 특별한 속성을 전달한다. 그리고 하위에서 상위로는 기본적으로 이벤트만 전달할 수 있다. 

 

보기가 어렵지만.. 먼저 상위 인스턴스에서 data를 정의해주었다. data이름은 fromParent

그리고 여기에서 하위 컴포넌트를 정의해준다 child-component.

 

cmp를 잘 보면 props가 있다. 이건 상위 컴포넌트(인스턴스)로 부터 값을 받아올 때 사용된다. html에 :data라고 적어서 data에 fromParent의 값을 받아오고 그걸 template안에서 사용할 수 있게 된다.

 

props를 배열 대신 오브젝트로 만들면 옵션을 지정해줄 수 있다. type을 지정할 수 있고, 또 디폴트 값을 설정할 수도 있다. 

그리고 만약 name이라는 값을 props로 받아오면 해당 컴포넌트의 data의 name이 있으면 안된다!!!

 

또한 받아온 props는 해당 컴포넌트에서 수정하면 안된다 methods등을 사용하여 변경하거나 하면 오류가 발생한다.

그리고 확인할 수 있는 부분이 인스턴스에선 데이터를 data : { } 이렇게 정의하지만 컴포넌트에선 data() { return {} } 이렇게 정의하는 것을 주목하자!

 

 

 

 

 

 하위에서 상위 컴포넌트로 이벤트 전달하기

앞서 배운 props는 상위에서 하위컴포넌트로 데이터를 전달하는 방식이다. 그럼 반대로 하위 컴포넌트에서 상위 컴포넌트로의 통신은 어떻게 할까?? 이벤트를 발생시켜 상위 컴포넌트에 신호를 보낸다. 상위 컴포넌트에서 하위 컴포넌트의 특정 이벤트가 발생하기를 기다리고 있다가 하위 컴포넌트에서 특정 이벤트가 발생하면 상위 컴포넌트에서 해당 이벤트를 수신하여 상위 컴포넌트의 메서드를 호출한다.

 

이벤트 버스를 활용하여 하위에서 상위로 데이터를 전달할 수도 있긴하다

 

이벤트의 발생과 수신은 $emit()과 v-on:속성을 사용하여 구현한다.

// 이벤트 발생
this.$emit('이벤트 명')

// 이벤트 수신
<child-component v-on:이벤트명='상위 컴포넌트의 메서드명'></child-component>

 

show 버튼을 클릭하면 @click='showLog'에 따라 showLog메서드가 실행이 된다.

showLog메서드 안에 this.$emit('show-log')가 실행되면서 show-log 이벤트가 발생한다.

show-log이벤트는 <child-component>에 정의한 @show-log에 전달되고 대상 메서드인 presentText메서드가 실행된다.

 

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

상위에서 하위로는 props를 전달하고 하위에서 상위로는 이벤트를 전달했다. 그럼 상위 - 하위 관계가 아니라 같은 레벨에 있는 컴포넌트끼리는 어떻게 통신을할까??

 

뷰는 상위에서 하위로만 데이터를 전달해야 하는 기본적인 통신 규칙을 따르기 때문에 바로 옆 컴포넌트에 값을 전달하려면 하위에서 공통 상위 컴포넌트로 이벤트를 전달한 후 공통 상위 컴포넌트에서 2개의 하위 컴포넌트에 props를 내려보내야 한다. 

 

하지만 이런 통신구조를 유지하면 상위 컴포넌트가 필요 없음에도 불그하고 같은 레벨 간에 통신하기 위해 강제로 상위 컴포넌트를 두어야 한다. 이를 해결할 수 있는 방법이 이벤트 버스이다.

 

 

별개의 새로운 인스턴스를 생성하고 보내는 컴포넌트에서는 .$emit()을, 받는 컴포넌트에서는 .$on() 구현해둔다.

아래의 예는 최상의 컴포넌트(인스턴스) 아래에 2개의 하위 컴포넌트가 있고 한 컴포넌트에서 다른 컴포넌트로 100이라는 값을 넘기는 것이다. 하나의 컴포넌트에 버튼을 누르면 showLog가 실행이되고 evtBus가 이벤트를 발생시킨다. 

다른 하나의 컴포넌트는 만들어졌을 때(created훅) evtBus에 리스너를 넣어둔다. 받아온 값을 데이터에 넣는 역할을 한다. 따라서 버튼을 클릭하면 기존의 0이었던 것이 100으로 바뀌게 된다.

 

'vue.js' 카테고리의 다른 글

vue에서 axios사용하기 3  (0) 2022.04.05
vue에서 axios 사용하기 2  (0) 2022.04.05
vue에서 axios 사용하기 1  (0) 2022.04.05
Vue 기초3  (0) 2022.04.02
Vue 기초 1  (0) 2022.04.01