[Vue] Vue Data management

한결·2023년 5월 3일
0

WEB

목록 보기
49/63

Vue Data management

Data in components

  • 한 페이지 내에 여러 component로 구분이 되어있음
    -> 근데 한 페이지 내에서 같은 데이터를 공유 해야 함

  • Child component에도 똑같은 data를 정의한다고 해서 그 부모 component의 data 가 변경된다고 Child component의 data도 변경되지 않는다
    -> 각 component는 독립적이기 때문 !

  • 그럼 필요한 컴포넌트들끼리 데이터를 주고 받으면?
    -> 데이터의 흐름을 파악하기 힘들다
    -> 개발 속도 저하
    -> 유지보수 난이도 증가

  • 컴포넌트는 부모-자식 관계를 가지고 있으므로,
    부모-자식 관계만 데이터를 주고받게 하자!!
    -> 데이터 흐름 파악 용이
    -> 유지보수 쉬워짐

pass props & emit event

  • 부모 -> 자식으로의 데이터 흐름
    • pass props의 방식
  • 자식 -> 부모로의 데이터 흐름
    • emit event의 방식

Pass Props

pass props

  • 요소의 속성(property)을 사용하여 데이터 전달
  • props는 부모 컴포넌트의 정보를 전달하기 위한 사용자 지정 특성
  • 자식 컴포넌트는 props옵션을 사용하여
    수신하는 props를 명시적으로 선언해야함

props in HelloWorld

  • 사실, 우리의 Vue app은 이미 props를 사용하고 있었다!

  • Vue CLI를 설치할 때 만들어주었던 App.vue의 HelloWorld 컴포넌트를 살펴보면 msg라는 property가 작성되어있음

  • HelloWorld.vue에서
    msg를 사용한 것을 확인할 수 있음

  • App.vue에서 property로 넘긴
    msg가 출력되는 것을 확인할 수 있음

props in HelloWorld 정리

  • App.vue의 요소에 msg="~" 라는 property를 설정하였고,
    하위 컴포넌트인 HelloWorld는 자신에게 부여된 msg property를
    template에서 {{ msg }}의 형태로 사용한 것

Pass Props

  • 이렇게 부모 => 자식으로의 data 전달 방식을 pass props라고 함
  • 정적인 데이터를 전달하는 경우 static props라고 명시하기도 함
  • 요소에 속성을 작성하듯이 사용 가능하여,
    prop-data-name="value"의 형태로 데이터를 전달
    • 이때 속성의 키 값은 kebab-case를 사용

  • Prop 명시
  • 데이터를 받는 쪽, 즉 하위 컴포넌트에서도
    props에 대해 명시적으로 작성 해주어야 함
  • 전달받은 props를 type과 함께 명시
  • 컴포넌트를 문서화할 뿐만 아니라,
    잘못된 타입이 전달하는 경우 브라우저의 자바스크립트 콘솔에서 사용자에게 경고

Pass Props convention

  • 부모에서 넘겨주는 props

    • kebab-case
      (HTML 속성명은 대소문자를 구분하지 않기 때문)
  • 자식에서 받는 props

    • camelCase
  • 부모 템플릿(html)에서 kebab-case로 넘긴 변수를 자식의 스크립트(vue)에서 자동으로 camelCase로 변환하여 인식

Dynamic props

  • 변수를 props로 전달할 수 있음
  • v-bind directive를 사용해 데이터를 동적으로 바인딩
  • 부모 컴포넌트의 데이터가 업데이트 되면
    자식 컴포넌트로 전달되는 데이터 또한 업데이트 됨

Dynamic props 실습

컴포넌트의 data 함수

  • 각 vue 인스턴스는 같은 data 객체를 공유하므로
    새로운 data 객체를 반환(return)하여 사용해야 함
data : function () {
  return {
    // component's data here
  }
}

Pass props

  • :dynamic-props="dynamicProps"

    앞의 key 값(dynamic-props)이란 이름으로
    뒤의 " "안에 오는 데이터(dynamicProps)를 전달하겠다는 뜻
  • 즉, :my-props="dynamicProps"로 데이터를 넘긴다면,
    자식 컴포넌트에서 myProps로 데이터를 받아야 함


  • v-bind로 묶여있는" "안의 구문은 javascript의 구문으로 볼 수 있음
    • 따라서 dynamicProps 라고 하는 변수에 대한 data를 전달할 수 있는 것
  • 그렇다면, 숫자를 props로 전달하기 위해서 다음 두 방법 중 어떤게 맞을까?
//1
<SomeComponent num-props="1"/>

//2
<SomeComponent :num-props="1">
  • 첫 번째 방식은 static props로 string으로써의 "1"을 전달
  • 두 번째 방식은 dynamic props로 숫자로써의 1을 전달

단방향 데이터 흐름

  • 모든 props는 부모에서 자식으로 즉 아래로 단방향 바인딩을 형성

  • 부모 속성이 업데이트되면 자식으로 흐르지만 반대 방향은 아님

    • 부모 컴포넌트가 업데이트될 때마다 자식 컴포넌트의 모든 prop들이 최신 값으로 새로고침 됨
  • 목적

    • 하위 컴포넌트가 실수로 상위 컴포넌트 상태를 변경하여 앱의 데이터 흐름을
      이해하기 힘들게 만드는 것을 방지
  • 하위 컴포넌트에서 prop를 변경하려고 시도해서는 안되며
    그렇게 하면 Vue는 콘솔에서 경고를 출력함

Emit Event

  • 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달할 때는 이벤트를 발생시킴

  • 이벤트를 발생시키는 게 어떻게 데이터를 전달하는 것이냐?

    1. 데이터를 이벤트 리스너의 콜백함수의 인자로 전달
    2. 상위 컴포넌트는 해당 이벤트를 통해 데이터를 받음

$emit

  • $emit 메서드를 통해 부모 컴포넌트에 이벤트를 발생

    • Semit('event-name') 형식으로 사용하며 부모 컴포넌트에
      event-name이라는 이벤트가 발생했다는 것을 알림
    • 마치 사용자가 마우스 클릭을 하면 click 이벤트가 발생하는 것처럼
      $emit('event-name')가 실행되면 event-name 이벤트가 발생하는 것
  • 참고) $

    • javascript는 변수에 $ 두개의 특수문자를 사용 가능
    • 이때, 기존에 사용하던 변수, 메서드들과 겹치지 않게 하기 위해서 vue는 $emit를 이벤트 전달을 위한 방식으로 택하였다.

Emit Event

  1. 자식 컴포넌트에 버튼을 만들고 클릭 이벤트를 추가
  2. $emit을 통해 부모 컴포넌트에게 child-to-parent 이벤트를 트리거

  • emit된 이벤트를 상위 컴포넌트에서 청취 후 핸들러 함수 실행

Emit Event 흐름 정리

  1. 자식 컴포넌트에 있는 버튼 클릭 이벤트를 청취하여
    연결된 핸들러 함수(ChildToParent) 호출

  2. 호출된 함수에서 $emit을 통해 상위 컴포넌트에 이벤트(child-to-parent) 발생

  3. 상위 컴포넌트는 자식 컴포넌트가 발생시킨 이벤트(child-to-parent)를 청취하여
    연결된 핸들러 함수(parentGetEvent) 호출

emit with data

  • 이벤트를 발생(emit) 시킬 때 인자로 데이터를 전달 가능

  • 이렇게 전달한 데이터는
    이벤트와 연결된 부모 컴포넌트의
    핸들러 함수의 인자로 사용 가능

emit with data 흐름 정리

  1. 자식 컴포넌트에 있는 버튼 클릭 이벤트를 청취하여
    연결된 핸들러 함수(ChildToParent) 호출

  2. 호출된 함수에서 $emit을 통해 부모 컴포넌트에 이벤트(child-to-parent)를 발생

    • 이벤트에 데이터(child data)를 함께 전달
  3. 부모 컴포넌트는 자식 컴포넌트의 이벤트 (child-to-parent)를 청취하여
    연결된 핸들러 함수(parentGetEvent) 호출,
    함수의 인자로 전달된 데이터(child data)가 포함되어 있음

  4. 호출된 함수에서 console.log(~child data~) 실행

emit with dynamic data

  • pass props와 마찬가지로 동적인 데이터도 전달 가능
  • 자식 컴포넌트에서 입력받은 데이터를
    부모 컴포넌트에게 전달하여 출력해보자

emit with dynamic data 흐름 정리

  1. 자식 컴포넌트에 있는 keyup.enter 이벤트를 청취하여
    연결된 핸들러 함수(ChildInput) 호출

  2. 호출된 함수에서 $emit을 통해 부모 컴포넌트에 이벤트(child-input)를 발생
    이벤트에 v-model로 바인딩 된 입력받은 데이터를 전달

  3. 상위 컴포넌트는 자식 컴포넌트의 이벤트(child-input)를 청취하여
    연결된 핸들러 함수(getDynamicData) 호출,
    함수의 인자로 전달된 데이터가 포함되어 있음

  4. 호출된 함수에서 console.log(~입력받은 데이터~) 실행

정리

  • 자식 컴포넌트에서 부모 컴포넌트로 이벤트를 발생시킴
    • 이벤트에 데이터를 담아 전달 가능
  • 부모 컴포넌트에서는 자식 컴포넌트의 이벤트를 청취
    • 전달받은 데이터는 이벤트 핸들러 함수의 인자로 사용

pass props/emit event

부모 -> 자식 -> 손자 -> 손자 자식 -> ,,,
: prop

자식의 자식의 자식 -> 자식의 자식 -> 자식 -> 부모
: emit

  • 아니 그래서 언제는 kebab-case고 언제는 camel Case야?
    -> HTML 요소에서 사용할 때는 kebab-case
    -> JavaScript에서 사용할 때는 camel Case

  • props

    • 상위 하위 흐름에서 HTML 요소로 내려줌 : kebab-case
    • 하위에서 받을 때 JavaScript 에서 받음 : camel Case
  • emit

    • emit 이벤트를 발생시키면 HTML 요소가 이벤트를 청취함 : kebab-case
    • 메서드, 변수명 등은 JavaScript 에서 사용함 : camel Case

0개의 댓글