[Vue.js] Props & Emit

2024. 7. 7. 20:58FE/Vue.js

 

 

Vue.js

Vue.js - The Progressive JavaScript Framework

vuejs.org

 

Vue.js

Vue.js - The Progressive JavaScript Framework

vuejs.org

 


1. Props

 

 

  • Props
    : 컴포넌트에 등록할 수 있는 사용자 정의 속성.
    : 상위 컴포넌트가 하위 컴포넌트에게 전달하는 값.

 


가. defineProps()

<!-- BlogPost.vue -->
<script setup>
const props = defineProps(['title'])
console.log(props.title)
</script>

<template>
  <h4>{{ title }}</h4>
</template>

defineProps<script setup> 내에서만 사용할 수 있는 compile-time macro다.

 

defineProps는 컴포넌트에 전달된 모든 props를 객체로 반환한다.

 

  • defineProps(['title'])
    : 부모 컴포넌트로부터 받아올 속성의 이름.
    : title이라는 속성값을 받아와 사용할 수 있다.
  • props.title : 필요한 경우 JavaScript에서 접근할 수 있다.

 

defineProps의 다양한 타입이 인자로 올 수 있다.

 

위에서는 배열이 인자로 왔다.

 

// <script setup>에서
defineProps({
  title: String,
})
// <script setup>가 아닐 때
export default {
  props: {
    title: String,
  }
}

 

하지만 객체를 인자로 전달하는 것을 추천한다.

 

<script setup>
const props = defineProps({
  // 기본 타입 체크
  //  (`null`과 `undefined`는 모든 타입에서 허용됩니다)
  propA: Number,
  // 여러 타입 허용
  propB: [String, Number],
  // 문자열 필수
  propC: {
    type: String,
    required: true
  },
  // 기본 값을 가지는 숫자형
  propD: {
    type: Number,
    default: 100
  },
  // 기본 값을 가지는 객체
  propE: {
    type: Object,
    // 객체 또는 배열 기본값은 팩토리 함수에서 반환되어야 합니다.
    // 함수는 컴포넌트에서 받은 rawProps를 인자로 받습니다.
    // (rawProps: 부모 컴포넌트에게 받은 props 전체 객체)
    default(rawProps) {
      return { message: '안녕!' }
    }
  },
  // 사용자 정의 유효성 검사 함수
  // 3.4+ 부터는 모든 props가 두 번째 인수로 전달 됨
  propF: {
    validator(value, props) {
      // 값은 다음 문자열 중 하나와 일치해야 합니다.
      return ['성공', '경고', '위험'].includes(value)
    }
  },
  // 기본값이 있는 함수
  propG: {
    type: Function,
    // 기본값 객체나 배열을 정의하는 팩토리 함수가 아니라
    // 기본값으로 사용할 함수입니다.
    default() {
      return 'Default function'
    }
  }
})
</script>

Props의 이름뿐 아니라 다양한 옵션도 추가할 수 있다.

 


나. 정적 Props

<BlogPost title="Vue와 함께한 나의 여행" />

 


다. 동적 Props

<!-- 변수 값을 동적으로 할당 -->
<BlogPost :title="post.title" />

<!-- 복잡한 표현식의 값을 동적으로 할당 -->
<BlogPost :title="post.title + ' by ' + post.author.name" />

 


라. 주의점

 

식 컴포넌트 내부에서 props를 변경하려 하면 안 된다.

 

Props는 읽기 전용입니다!

 

모든 props는 자식 속성과 부모 속성 사이에 하향식 단방향 바인딩을 형성한다.

 

부모 property가 업데이트되면 자식도 업데이트되지만 그 반대는 안된다.

 

앱에서의 데이터 흐름을 이해하기 어렵기 때문에 금지한다.

 


2. Emit

 

 

 

props는 부모에서 자식으로 업데이트되는 하향식 단방향 바인딩만 지원한다.

 

자식 컴포넌트에서 부모 컴포넌트의 property를 수정할 순 없다.

 

대신에 자식 컴포넌트에서 부모 컴포넌트로 이벤트는 보낼 순 있다.

 


가. $emit

<!-- 자식 컴포넌트 -->
<template>
    <button @click="$emit('updateEvent', '새로운 값')">이벤트 발생</button>
</template>
  • $emit('eventName', ...args)
    : 자식 컴포넌트에서 이벤트를 발생시켜서 부모 컴포넌트로 데이터를 전달하는 메서드
    : $는 Vue에서 제공되는 전역 속성이나 메서드를 식별하기 위한 접두사

 


나. defineEmits()

<!-- 자식 컴포넌트 -->
<template>
  <button @click="emitEvent">이벤트 발생</button>
</template>

<script setup>
const emit = defineEmits(['updateEvent'])

const emitEvent = () => {
  emit('updateEvent', '새로운 값')
}
</script>

$emit 대신에 defineEmits()를 사용하여 명시적으로 발신할 이벤트를 선언할 수 있다.

 

위의 코드에서 버튼을 누르면 emitEvent 함수가 실행된다.

 

emitEventupdateEvent라는 이벤트를 부모 컴포넌트에게 전달한다.

(이벤트 이름은 자유다.)

 


다. 이벤트 처리

<!-- 부모 컴포넌트 -->
<script setup>
const a = ref("오래된 값");
</script>

<ChildCoponent @updateEvent="(v) => a = v" />

부모 컴포넌트에서는 보내진 이벤트를 받아 처리한다.

 

<!-- 부모 컴포넌트 -->
<script setup>
const a = ref("오래된 값");
const updateHandler = (v) => {
    a = v;
};
</script>

<!-- 또는 이벤트를 처리할 함수를 지정할 수 있다. -->
<ChildComponent @updateEvent="updateHandle" />

이벤트를 처리할 콜백함수를 지정할 수도 있다.

 


라. Event Name Casing

<!-- 자식 컴포넌트 -->
<button @click="$emit('updateEvent', '새로운 값')">이벤트 발생</button>
<!-- 또는 -->
<script setup>
...
const emit = defineEmits(['updateEvent'])
const emitEvent = () => {
  emit('updateEvent', '새로운 값')
}
</script>

자식 컴포넌트에서 이벤트를 선언하고 발신할 때 → camelCase

 

<ChildComponent @updateEvent="updateHandle" />
<!-- 보다는 -->
<ChildComponent @update-event="updateHandle" />

부모 컴포넌트에서 수신 시 → kebab-case

 

HTML 속성은 대소문자를 구분하지 않기 때문에 camelCase 표기법을 사용하면 문제가 생길 수 있다.

 


'FE > Vue.js' 카테고리의 다른 글

[Vue.js] Pinia  (0) 2024.07.07
[Vue.js] Vue-Router  (0) 2024.07.07
[Vue.js] Component  (0) 2024.07.07
[Vue.js] Watchers  (0) 2024.07.07
[Vue.js] 이벤트 핸들링  (0) 2024.07.07