Vue - Props

2023. 8. 3. 16:42·📘 Frontend/Vue

Vue Props

같은 컴포넌트를 사용할 때 서로 다른 데이터를 출력하기 위한 개념이자 일종의 Custom HTML 속성이다.

Vue App에 Props를 정의할 때는 카멜케이스, HTML내 Custom Tag에 Props를 정의할떈 케밥케이스 (- 를 이용함)를 사용한다.

Props는 Data 프로퍼티와 동일하게 취급되며 배열을 값으로 가질수도 있고, 객체를 가질수도 있다.

팀으로 협업을 한다면 왠만하면 객체를 값으로 가지는게 좋다.

props: [
    'name',
    'phoneNumber',
    'emailAddress'
]

<friend-contact name="a" phone-number="1" email-address="a@a.com"></friend-contact>
<friend-contact name="b" phone-number="2" email-address="b@b.com"></friend-contact>

또, Props는 Immutable하기 때문에 단방향 데이터 플로우에 위반하면 Vue App이 실행되지 않습니다.

즉, Custom HTML Tag에서 데이터를 변경하면 안되고 부모인 Vue App에서 변경 후 Custom HTML 로 반영해야 합니다.

그러기 위해선 Data 프로퍼티를 만들어서 초기값을 Props의 프로퍼티로 지정 후 해당 데이터 프로퍼티를 출력하면 됩니다.

이 방법은 원본 데이터를 그대로 변경하는게 아니라 내부값을 통하고 원본값 변경은 나중에 다뤄보겠습니다.


지원되는 프로퍼티 값

일반적으로 다음 공식 문서에서 프로퍼티 유효성 검사에 대한 모든 것을 배울 수 있습니다. https://v3.vuejs.org/guide/component-props.html


특히 다음 값 타입(type 프로퍼티)이 지원됩니다.

  • 문자열(String)

  • 숫자(Number)

  • 불리언(Boolean)

  • 배열(Array)

  • 객체(Object)

  • 날짜(Date)

  • 함수(Function)

  • 심볼(Symbol)


생성자 함수(Date와 같은 내장된 함수 또는 커스텀 함수)도 타입이 될 수 있습니다.

props: {
    name: {
        type: String,
        required: true
    },

    phoneNumber: {
        type: String,
        required: false
        validator: function(value) {
            return value === '1' || value === '0';
        }
    }
}

Main Vue App

<template>  
  <section>  
    <header>  
      <h1>My Friends</h1>  
    </header>  
    <ul>  
      <friend-contact  
          v-for="friend in friends"  
          key="friend.id"  
          :name="friend.name"  
          :phone-number="friend.phone"  
          :email-address="friend.email"  
          :is-favorite="true">  
      </friend-contact>  
    </ul>  
  </section>  
</template>  

<script>  
export default {  
  data() {  
    return {  
      friends: [  
        {  
          id: "manuel",  
          name: "Manuel Lorenz",  
          phone: "0123 45678 90",  
          email: "manuel@localhost.com",  
        },  
        {  
          id: "julie",  
          name: "Julie Jones",  
          phone: "0987 654421 21",  
          email: "julie@localhost.com",  
        },  
      ],  
    };  
  },  
};  
</script>  

<style>  
* {  
  box-sizing: border-box;  
}  

html {  
  font-family: "Jost", sans-serif;  
}  

body {  
  margin: 0;  
}  

header {  
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);  
  margin: 3rem auto;  
  border-radius: 10px;  
  padding: 1rem;  
  background-color: #58004d;  
  color: white;  
  text-align: center;  
  width: 90%;  
  max-width: 40rem;  
}  

#app ul {  
  margin: 0;  
  padding: 0;  
  list-style: none;  
}  

#app li {  
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);  
  margin: 1rem auto;  
  border-radius: 10px;  
  padding: 1rem;  
  text-align: center;  
  width: 90%;  
  max-width: 40rem;  
}  

#app h2 {  
  font-size: 2rem;  
  border-bottom: 4px solid #ccc;  
  color: #58004d;  
  margin: 0 0 1rem 0;  
}  

#app button {  
  font: inherit;  
  cursor: pointer;  
  border: 1px solid #ff0077;  
  background-color: #ff0077;  
  color: white;  
  padding: 0.05rem 1rem;  
  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.26);  
}  

#app button:hover,  
#app button:active {  
  background-color: #ec3169;  
  border-color: #ec3169;  
  box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.26);  
}  
</style>

Friend Component

<template>  
  <li>  
    <h2>{{ name }} {{ friendIsFavorite ? '(Favorite)' : '' }}</h2>  
    <button @click="toggleDetails">{{ detailsAreVisible ? 'Hide' : 'Show' }} Details</button>  
    <button @click="toggleFavorite">Details</button>  

    <ul v-if="detailsAreVisible">  
      <li>  
        <strong>Phone:</strong>  
        {{ phoneNumber }}  
      </li>  
      <li>  
        <strong>Email:</strong>  
        {{ emailAddress }}  
      </li>  
    </ul>  
  </li>  
</template>  

<script>  
export default {  
  // props: ["name", "phoneNumber", "emailAddress", "isFavorite"],  
  props: {  
    name: {  
      type: String,  
      required: true  
    },  
    phoneNumber: {  
      type: String,  
      required: true  
    },  
    emailAddress: {  
      type: String,  
      required: true  
    },  
    isFavorite: {  
      type: Boolean,  
      required: false,  
      default: false,  
      // validator: function(value) {  
      //   return value === '1' || value === '0';      // }    }  
  },  
  data() {  
    return {  
      detailsAreVisible: false,  
      friendIsFavorite: this.isFavorite,  
    };  
  },  
  methods: {  
    toggleDetails() {  
      this.detailsAreVisible = !this.detailsAreVisible;  
    },  
    toggleFavorite() {  
      this.friendIsFavorite = !this.friendIsFavorite;  
    }  
  }  
};  
</script>
저작자표시 (새창열림)

'📘 Frontend > Vue' 카테고리의 다른 글

Vue - 빠른 학습을 위한 기록 잠정 중단  (0) 2023.08.05
Vue - Component Custom Event ($emit())  (0) 2023.08.03
Vue - Component Basic  (0) 2023.08.02
Vue - Monster Slayer Game 만들기 1 : 공격 기능 추가  (3) 2023.07.31
Vue - V-for Advanced : Object Looping & Indexing  (0) 2023.07.31
'📘 Frontend/Vue' 카테고리의 다른 글
  • Vue - 빠른 학습을 위한 기록 잠정 중단
  • Vue - Component Custom Event ($emit())
  • Vue - Component Basic
  • Vue - Monster Slayer Game 만들기 1 : 공격 기능 추가
신건우
신건우
조용한 개발자
  • 신건우
    우주먼지
    신건우
  • 전체
    오늘
    어제
    • 분류 전체보기 (422)
      • 📘 Frontend (71)
        • Markup (1)
        • Style Sheet (2)
        • Dart (8)
        • Javascript (12)
        • TypeScript (1)
        • Vue (36)
        • React (2)
        • Flutter (9)
      • 📘 Backend (143)
        • Java (34)
        • Concurrency (19)
        • Reflection (1)
        • Kotlin (29)
        • Python (1)
        • Spring (42)
        • Spring Cloud (5)
        • Message Broker (5)
        • Streaming (2)
        • 기능 개발 (5)
      • 💻 Server (6)
        • Linux (6)
      • ❌ Error Handling (11)
      • 📦 Database (62)
        • SQL (31)
        • NoSQL (2)
        • JPQL (9)
        • QueryDSL (12)
        • Basic (4)
        • Firebase (4)
      • ⚙️ Ops (57)
        • CS (6)
        • AWS (9)
        • Docker (8)
        • Kubernetes (13)
        • MSA (1)
        • CI & CD (20)
      • 📚 Data Architect (48)
        • Data Structure (10)
        • Algorithm (8)
        • Programmers (17)
        • BaekJoon (5)
        • CodeUp (4)
        • Design Pattern (4)
        • AI (0)
      • ⚒️ Management & Tool (8)
        • Git (7)
        • IntelliJ (1)
      • 📄 Document (10)
        • Project 설계 (6)
        • Server Migration (3)
      • 📄 책읽기 (2)
        • 시작하세요! 도커 & 쿠버네티스 (2)
      • 🎮 Game (4)
        • Stardew Vally (1)
        • Path of Exile (3)
  • 블로그 메뉴

    • 링크

      • Github
    • 공지사항

    • 인기 글

    • 태그

      React #Markdown
      Lock #Thread #Concurrency
      GStreamer #Pipeline
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.0
    신건우
    Vue - Props
    상단으로

    티스토리툴바