ice rabbit programming

[vue] 컴포넌트 간 통신에 v-model 활용하기 본문

Development/JavaScript

[vue] 컴포넌트 간 통신에 v-model 활용하기

판교토끼 2021. 3. 8. 01:18

이 글을 검색으로 들어온 개발자라면 v-model에 대해서는 능숙하게 사용하겠지만, 앞 부분에서 간단하게만 짚고 넘어가겠다. 아래의 링크들은 모두 vue 공식 문서(한글)로 연결되어 있다.

v-model

웹 프론트엔드나 클라이언트 프로그래밍은 사용자에게 직접 데이터를 제공하고 입력받는 UI를 다룬다. 이 데이터를 내부 로직으로 처리하거나 서버로 보내 처리하는 등의 과정이 필요하기 때문에, UI와 데이터 간의 바인딩이 필수적이다.

vue에서는 v-model이라는 키워드로 바인딩을 제공한다. 아래처럼 쓸 수 있다.

// ...
<input
  id="data"
  v-model="myData" />
// ...

data() {
  myData: ''
}

input의 value가 myData로 바인딩되어, 초깃값 설정 및 입력 시 담는 등의 활용이 가능해진다.

컴포넌트 간의 통신

이번 포스팅의 주제는 v-model보다는 컴포넌트 간의 통신이 주를 이룬다. 기본적으로 부모->자식으로의 데이터 전달은 props를 통해, 자식->부모로의 데이터 전달은 이벤트 발생(emit)을 통해 이루어진다. 양방향 바인딩(.sync)을 2.3.0 이상 버전에서 제공하고 있으나, 웬만한 경우에는 사용을 지양하는 것을 권하고 있다. 자식 컴포넌트가 부모 컴포넌트 요소를 임의로 변경할 경우, 그 요소는 어디서 변경된건지를 특정할 수 없는 문제가 있기 때문이다.

props 예시

// 자식
// ...
props: [
  'myProp',
  'myProp2',
],
// ...
// 부모
// ...
<my-component
  myData="1"
  myData2="2" />
// ...

이런 식으로 자식 컴포넌트의 vue app 내부에서 prop을 정의하고, 부모에서는 해당 컴포넌트를 렌더링할 때 props에 해당하는 데이터를 넘겨준다.

event emit 예시

// 자식
// ...
<input
  v-model="value"
  @change="onDataChanged" />
// ...
props: [
  'value',
],
// ...
onDataChanged() {
  this.$emit('input', this.value) // input 이벤트 발생
}
// 부모
// ...
<my-component
  value="1"
  @input="onChanged" />
// ...
onChanged(myData) {
  this.parentData = myData
}

이런 식으로 emit 시에 데이터를 넘겨줄 수 있고(이벤트 이름은 원하는대로 지정해주면 된다), 받는 쪽에서는 함수의 인자로 넣어주면 사용할 수 있다.

props + emit = v-model

sync를 사용하지 않는 경우, 위 과정처럼 컴포넌트 간 통신을 구현해야 한다. vue에서는 많은 축약형(shortly) 키워드를 제공하는데, 이 경우에도 v-model 키워드를 사용해 생산성을 대폭 높일 수 있다.

위의 두 예시는 아래 코드와 완전히 같다.

// 자식
// ...
<input
  v-model="value"
  @change="onDataChanged" />
// ...
props: [
  'value',
],
// ...
onDataChanged() {
  this.$emit('input', this.value) // input 이벤트 발생
}
// 부모
// ...
<my-component
  v-model="parentData" />
// ...

부모에서 자식 컴포넌트 태그에 v-model을 사용하면, 해당 data가 자식의 props로 넘어가고 자식에서 이벤트를 발생시켰을 경우 넘긴 데이터가 변수에 할당된다.

별도 지정이 없을 경우 default로 자식의 props는 value로 지정되고, 자식에서 보내는 이벤트는 input 이벤트가 지정된다. props 명이나 이벤트명을 커스텀할 수도 있다. 이 때, 자식에서 받는 props는 명시적으로 설정해주어야 한다. 

 

처음에 본인은 v-model이 컴포넌트에 적용될 수 있는지 모르고 props 넘기는 것과 event 발생을 직접적으로 구현했었는데, v-model로 적용하니 공수가 꽤나 많이 줄어든 것을 체감할 수 있었다.