12. Props 속성의 특징과 실습

29102 단어 vue.jsvue.js

캡틴판교 장기효님의 Vue.js시작하기 인프런 강의를 수강하고 내용을 정리했다.
매일 20분 야금야금 Vue.js 화이팅.

IDE: Visual Studio Code
크롬 뷰 개발자 도구: Vue.js devtools


Props 속성

컴포넌트 간에 상위/하위 관계가 있다.
Props 속성을 이용하여 상위 컴포넌트의 데이터를 하위 컴포넌트가 내려받을 수 있다.
상위 컴포넌트의 데이터 속성이 바뀌면, 하위 컴포넌트의 Props 속성이 내려받는다.

Props 속성의 Reactivity

Root 컴포넌트에 속한 app-header 컴포넌트가 있다.
Root 컴포넌트에 message 라는 데이터가 있다.
하위 컴포넌트는 props 속성을 propsdata라고 이름 붙였다.

Props 속성 문법으로 데이터 내려받기

app-header의 propsdata가 Root의 message 를 내려받는다.

<app-header v-bind:propsdata="message">/</app-header>

데이터 바인딩으로 확인하자

데이터 바인딩은 Vue.js의 문법이다.

{{ }} 을 이용한다.
Vue.js의 데이터를 Html에 삽입하는 단방향 바인딩.

Root 컴포넌트의 데이터인 message 를 변경하면, app-header 에 직접 보이게 하자.

        var appHeader = {
            template: '<h1>{{ propsdata }}</h1>',
            props: ['propsdata']    
        }

propsdata 라는 Vue.js의 데이터를 {{ }}문법으로 바인딩 해줬다.

코드를 저장하고, 'Live Server'로 실행하자.
개발자 도구를 열어서 vue 를 확인하자.

AppHeader의 'hi'

message를 'bye'로 바꾸기

아래처럼 직접 루트 컴포넌트의 message 내용을 'bye'로 바꾸고 저장한다.

app-header에서 노출되는 propsdata 값이 즉시 bye로 바뀜을 확인할 수 있다.
이를 통해 Props 속성의 Reactivity를 확인했다.

전체 코드는 아래와 같다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <div id="app">
        <!-- <app-header v-bind:프롭스 속성 이름="상위 컴포넌트의 데이터 이름"></app-header> -->
        <app-header v-bind:propsdata="message">/</app-header>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appHeader = {
            template: '<h1>{{ propsdata }}</h1>',
            props: ['propsdata']    
        }

        // 뷰 인스턴스 
        new Vue({
            el: '#app',
            components: {
                'app-header': appHeader
            },
            data:{
                message: 'hi'
            }
        })
        
    </script>

</body>
</html>

Props 실습

기존 코드에 아래의 요구사항 추가하자.

  1. Root 컴포넌트에 num : 10 이라는 data를 추가하자.
  2. Root 컴포넌트에 app-content 라는 하위 컴포넌트를 하나 등록하자.
  3. app-content 컴포넌트는 template 속성과 props 속성을 가진다.
  4. Root 컴포넌트의 num 을 내려받는 Props 속성을 app-content에 연결하자.

Root 컴포넌트

message 와 num이라는 데이터가 속해있다.
message 의 값은 'hi'이고, num의 값은 10 이다.

app-header 컴포넌트의 Props 속성

app-header 컴포넌트가 Root 컴포넌트의 message를 내려받았다.

app-content 컴포넌트의 Props 속성

app-content 컴포넌트가 Root 컴포넌트의 num을 내려받았다.

실습 코드는 아래와 같다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <div id="app">
        <!-- <app-header v-bind:프롭스 속성 이름="상위 컴포넌트의 데이터 이름"></app-header> -->
        <app-header v-bind:propsdata="message">/</app-header>
        <app-content v-bind:propsnum="num"></app-content>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appHeader = {
            template: '<h1>AppHeader: {{ propsdata }}</h1>',
            props: ['propsdata']    
        }

        var appContent = {
            template: '<div>AppContent: {{propsnum}}</div>',
            props: ['propsnum']
        }

        // 뷰 인스턴스 
        new Vue({
            el: '#app',
            components: {
                'app-header': appHeader,
                'app-content': appContent
            },
            data:{
                message: 'hi',
                num: 10
            }
        })
        
    </script>

</body>
</html>

app-content를 아래와 같이 정의했는데,
실습 풀이를 듣고나니 각 컴포넌트마다 props 속성의 이름은 똑같아도 된다고 한다.
컴포넌트마다의 고유 영역이기 때문이다.

        var appHeader = {
            template: '<h1>AppHeader: {{ propsdata }}</h1>',
            props: ['propsdata']    
        }
        var appContent = {
            template: '<div>AppContent: {{propsnum}}</div>',
            props: ['propsnum']
        }

즉, 이렇게 써도 된다.

        var appHeader = {
            template: '<h1>AppHeader: {{ propsdata }}</h1>',
            props: ['propsdata']    
        }
        var appContent = {
            template: '<div>AppContent: {{propsdata}}</div>',
            props: ['propsdata']
        }

정상 동작하는 전체코드

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <div id="app">
        <!-- <app-header v-bind:프롭스 속성 이름="상위 컴포넌트의 데이터 이름"></app-header> -->
        <app-header v-bind:propsdata="message">/</app-header>
        <app-content v-bind:propsdata="num"></app-content>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appHeader = {
            template: '<h1>AppHeader: {{ propsdata }}</h1>',
            props: ['propsdata']    
        }

        var appContent = {
            template: '<div>AppContent: {{propsdata}}</div>',
            props: ['propsdata']
        }

        // 뷰 인스턴스 
        new Vue({
            el: '#app',
            components: {
                'app-header': appHeader,
                'app-content': appContent
            },
            data:{
                message: 'hi',
                num: 10
            }
        })
        
    </script>
</body>
</html>

다음 시간에는 하위 컴포넌트에서 상위 컴포넌트로 이벤트를 올려주는 event emit에 대해 배운다.


참고

단방향 바인딩

Vue.js의 데이터를 HTML에 삽입
{{ }}

양방향 바인딩

v-model
Vue.js의 데이터를 HTML에 삽입
그리고
HTML의 데이터를 Vue.js에 삽입

폼 입력 바인딩 - Vue.js 공식 문서

좋은 웹페이지 즐겨찾기