[Vue] Props : 부모 컴포넌트 → 자식 컴포넌트로 데이터 전달하기(chart.js 예시)

yunulog·2022년 10월 25일
0

Vue

목록 보기
6/7

Vue로 작업을 하다 보면, 컴포넌트 안에 컴포넌트를 구성하여서 작업을 해야하는 경우가 있다. 나의 경우에는, 컴포넌트 안에 그래프 컴포넌트를 구성하여 작업한 적이 있다.
그 때, 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달해야 하는 경우가 생기는데 이런 경우에 사용하는데 Props 이다.

부모 컴포넌트와 자식 컴포넌트

부모 컴포넌트와 자식 컴포넌트에 대해서 우선 간단하게 알아보고 가겠다. 위의 예시처럼 어떤 컴포넌트 안에 하나 또는 둘 이상의 컴포넌트를 종속시켜서 활용하는 경우가 생긴다.

이때 다른 컴포넌트를 감싸안는 더 큰 컴포넌트를 부모 컴포넌트라고 하고, 부모 컴포넌트에 종속되는 컴포넌트를 자식 컴포넌트라고 부른다.
다른 말로 각각 상위 컴포넌트, 하위 컴포넌트라고 부르기도 한다.

컴포넌트 간 데이터 전달: Props

부모 컴포넌트에서 하위 컴포넌트로 데이터를 전달해야 하는 상황이 생기는데 이 때 사용하는 것이 Props이다.

예를 들어 데이터를 분석하는 페이지를 만들고자 한다. 페이지 레이아웃을 만들고 그 안에 그래프를 넣어야 하는데, 이 때 그래프를 별도의 컴포넌트로 구성하여 넣으려 한다.
이 때 레이아웃 페이지는 부모 컴포넌트가 되고, 그래프 컴포넌트를 자식 컴포넌트가 된다.
부모 컴포넌트에서는 메소드를 이용해 데이터를 가져올 것이다. 그래프 컴포넌트에서는 그 데이터를 이용해서 그래프를 그려야하는데 부모 컴포넌트에서 그 데이터를 받아와야 한다.

부모 컴포넌트에서 데이터 넘기기

부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하기 위해서는 부모 컴포넌트에서 자식 컴포넌트를 HTML 태그로 불러온 후 태그 안에서 데이터를 넘겨주면 된다.

# parent component
<template>
  <child msg="Hello"></child>
</template>

HTML 태그 안에 데이터를 정의해주면 자식 컴포넌트에서 데이터를 받을 수 있게 된다.

유의할 점은 위에서 사용된 방식은 동적인 바인딩이 아니라는 것이다. 따라서 데이터가 바뀌더라도 하위 컴포넌트는 이를 반영하지 못한다.

동적으로 데이터 넘기기

v-bind를 이용하면 데이터를 동적으로 넘길 수 있다. 즉, 데이터가 변하게 되면 자식 컴포넌트에서도 이 변화를 감지하고 반영하게 된다.

# parent component
<template>
  <input v-model="parentMsg">
  <br>
  <child v-bind:msg="parentMsg"></child>
</template>

이런식으로 v-bind를 이용해 데이터를 전달해주면 동적으로 데이터가 전달된다. parentMsg에 입력된 값이 바뀌면 자식 컴포넌트로도 변화된 값이 재전달될 것이다.

v-bind::라는 약어로도 쓸 수 있고 실제로 이 방식이 더 많이 쓰인다.

# parent component

<template>
  <input v-model="parentMsg">
  <br>
  <child :msg="parentMsg"></child>
</template>

자식 컴포넌트에서 데이터 받기

위처럼 부모 컴포넌트에서 전달된 데이터는 자식 컴포넌트에서 Props를 이용해 받을 수 있다.

# child component

export default {
  props: {
    msg: String
  }

이런식으로 변수의 유형을 결정해두면 된다.

Props 속성 종류

1. 타입 지정

export default {
  props: {
    msg: Number
  }

→ msg는 숫자 타입이다.
Prop은 다음 유형들을 지정할 수 있다.
String, Number, Boolean, Function, Object, Array, Symbol
'null'로 지정하면 어떤 유형이든 가능하다는 뜻이 된다.

2. 여러 개의 가능한 타입

export default {
  props: {
    msg: [String, Number]
  }

→ msg는 문자열이나 숫자 타입이어야 한다.

3. 필수 여부 지정

export default {
  props: {
    msg: {type: String,
         required: true
    }
  }

→ msg는 문자열이며 필수 값이다.

4. 기본값 지정

export default {
  props: {
    msg: {type: String,
         default: 'Hello'
    }
  }

→ msg는 문자열이며 기본 값은 'Hello'이다.

5. 함수 값 반환

export default {
  props: {
    msg: {type: Object,
          default: function () {
            return { message: 'hello' }
      }
    }
  }

→ msg는 객체이며 기본 값은 함수에서 반환된다.

Chart.js 예시

Props에 대한 개념이 확실하지 않은 상황에서 chart.js를 사용하려다가 골머리를 앓았던 기억이 있어서 이 예시를 준비했다.

부모 컴포넌트에서 페이지 레이아웃을 만들고 자식 컴포넌트에서 Chart.js 라이브러리를 이용한 그래프를 구성하려고 한다.

<부모 컴포넌트>

<template>
  <h1>원 그래프</h1>
  <PieChart
  :data1 = "50"
  :data2 = "30"
  :data3 = "20">
  </PieChart>
</template>

<script>
//자식 컴포넌트 불러오기
import PieChart from '@/components/chart/Pie.vue'
export default {
	components: { PieChart }
}
</script>

부모 컴포넌트에서 data1,2,3에 각각 50,30,20 을 전달했다.

<자식 컴포넌트(그래프)>

<template>
  <Pie
    :chart-options="chartOptions"
    :chart-data="chartData"
  />
</template>

<script>
import { Pie } from 'vue-chartjs/legacy'

import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  ArcElement,
  CategoryScale
} from 'chart.js'

ChartJS.register(Title, Tooltip, Legend, ArcElement, CategoryScale)

export default {
  name: 'PieUserChart',
  components: {
    Pie
  },
  props: {
    data1: {
      type: Number
    },
    data2: {
      type: Number
    },
    data3: {
      type: Number
    }
  },
  // 값이 바뀔때마다 dataset 재설정하기
  watch: {
    percentCarbohydrate () {
      this.chartData.datasets[0].data = [parseInt(this.data1), parseInt(this.data2), parseInt(this.data3)]
    }
  },
  data () {
    return {
      chartData: {
        labels: ['탄수화물', '단백질', '지방'],
        datasets: [
          {
            label: '권장 섭취량',
            backgroundColor: ['#ffce56', '#37a2eb', '#fe6484'],
            data: []
          }
        ]
      },
      chartOptions: {
        responsive: true,
        maintainAspectRatio: false
      }
    }
  }
}
</script>

자식 컴포넌트에서는 Props를 이용해 부모 컴포넌트로부터 받아온 data1,2,3을 전달받고 이를 데이터셋에 설정하여 그래프를 완성시킨다.
(수많은 옵션 등의 기본 설정들은 간략한 예시를 위해 모두 지웠다)

<참조>

0개의 댓글