본문 바로가기

Vue.js

[Udemy Vue 완벽가이드 Section8] 100. 프로퍼티/이벤트 폴스루 및 모든 프로퍼티 바인딩하기

다음 두 가지 심화개념을 알아보자.

  • 폴스루(fallthrough:대체) 프로퍼티
  • 컴포넌트의 모든 프로퍼티 바인딩하기

 

1/ 폴스루(fallthrough) 프로퍼티

# 정의

- 등록(정의)하지 않은 props를 컴포넌트 내부에 설정하거나, 등록하지 않은 (커스텀)이벤트를 컴포넌트 내부에서 수신할 수 있다.

- 컴포넌트에 전달되는 속성(props) 또는 v-on 이벤트 리스너이지만, 이것을 받는 컴포넌트의 props 또는 emits에서 명시적으로 선언되지 않은 속성. (Non-Prop 속성)

- 일반적인 예로는 class, style, id 속성이 있다.

 

컴포넌트가 싱글 루트 엘리먼트를 렌더링하면, 폴스루 속성이 루트 엘리먼트의 속성에 자동으로 추가된다.

 

# 예시

예를 들어, <MyButton> 템플릿이 있는 컴포넌트가 있다고 해보자.

<!-- <MyButton>의 템플릿 -->
<button>클릭하기</button>

 

그리고 이 MyButton컴포넌트를 사용하는 부모 컴포넌트가 있다.

<MyButton class="large" />

 

 

최종 렌더링된 DOM은 다음과 같다.

<button class="large">클릭하기</button>

 

<MyButton>은 class를 accepted props로서 선언하지 않았다. 따라서, class는 fallthrough attribute로 처리되어 <MyButton>의 루트 엘리먼트에 자동으로 추가된다.

 

# class와 style의 병합

자식 컴포넌트의 루트 엘리먼트에 이미 class 또는 style 속성이 있는 경우, 상위 엘리먼트에서 상속된 class 또는 style값과 병합된다.

 

이전 예에서 <MyButton>의 템플릿을 다음과 같이 변경한다면,

<!-- <MyButton>의 템플릿 -->
<button class="btn">클릭하기</button>
<!--부모 컴포넌트-->
<MyButton class="large" />

 

최종 렌더링된 DOM은 아래와 같다.

<button class="btn large">클릭하기</button> <!--fallthrough 속성과 기존 class속성이 병합-->

 

# v-on 리스너 상속

v-on 이벤트 리스너에도 동일한 규칙이 적용된다.

<MyButton @click="onClick" />

 

click 리스너는 <MyButton>의 루트 엘리먼트인 <button> 엘리먼트에 추가된다.

<button @click="onClick">클릭하기</button>

<button>을 클릭하면 부모 컴포넌트의 onClick 메서드가 트리거된다.

만약 <button>에 이미 v-on으로 바인딩 된 click 리스너가 있는 경우, 두 리스너 모두 트리거된다.

 

 

# 속성 상속 비활성화

만약 자식 컴포넌트가 속성을 자동으로 상속받지 않도록 하려면

→ 컴포넌트의 옵션에서 inheritAttrs: false 를 설정하면 된다.

 

속성 상속을 비활성화하는 일반적인 시나리오는 루트 노드 이외의 다른 엘리먼트에 속성을 적용해야하는 경우.

inheritAttrs 옵션을 false로 설정하면, 폴스루 속성을 적용해야하는 위치를 완전히 제어할 수 있다.

이러한 폴스루 속성은 템플릿 표현식에서 $attrs로 직접 접근할 수 있다.

<span>폴스루 속성: {{ $attrs }}</span>

 

$attrs 객체에는 컴포넌트의 props 또는 emits 옵션으로 선언되지 않은 모든 속성(예: class, style, v-on 리스너 등 폴스루 속성)이 포함된다.

위 : console.log로 $attrs.onClick을 찍었을 때.

아래 : class="hohoho"가 폴스루 속성인 경우, console.log로 $attrs를 찍었을 때.

 

 

참고 :

- props와 달리 폴스루 속성은 JavaScript에서 원 표기를 유지하므로, foo-bar와 같은 속성은 $attrs['foo-bar']로 접근해야한다. ($attrs.fooBar가 아니다.)

- @click과 같은 v-on 이벤트 리스너는 $attrs.onClick 속성에 노출된다.

 

 

때로는 스타일 지정을 위해 실제 <button> 엘리먼트를 <div>로 추가 래핑해야 할 수도 있다.

<div class="btn-wrapper">
  <button class="btn">클릭하기</button>
</div>

 

 

# 루트 엘리먼트가 아닌 곳에 폴스루 속성 적용방법

여기서 clas 및 v-on 리스너와 같은 폴스루 속성이 외부 <div>가 아닌 내부 <button>에 적용되기를 원하면,

inheritAttrs: false로 설정하고, 원하는 요소에 v-bind="$attrs"로 이를 구현할 수 있다.

<div class="btn-wrapper">
  <button class="btn" v-bind="$attrs">클릭하기</button>
</div>

 

 

# 다중 루트 노드에서 속성 상속

단일 루트 노드가 있는 컴포넌트와 달리, 여러 루트 노드가 있는 컴포넌트에는 자동 속성 폴스루 동작이 없다.

$attrs가 명시적으로 바인딩되지 않은 경우, 런타임 경고가 발행된다.

<!--부모 컴포넌트-->
<CustomLayout id="custom-layout" @click="changeValue" />

 

<CustomLayout>에 다음과 같은 다중 루트 템플릿이 있는 경우, Vue가 폴스루 속성을 적용할 위치를 확신할 수 없기 때문에 경고가 표시된다.

<!--CustomLayout 컴포넌트-->
<header>...</header>
<main>...</main>
<footer>...</footer>

 

$attrs 가 명시적으로 바인딩되면, 경고가 표시되지 않는다.

<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>

 

# JavaScript에서 폴스루 속성 접근하기

필요한 경우, $attrs 인스턴스 속성을 통해 컴포넌트의 폴스루 속성에 접근할 수 있다.

export default {
 created() {
  console.log(this.$attrs);
 }
}

 

 

 

2/ 모든 프로퍼티 바인딩

props와 관련된 또 다른 내장기능/동작이 있다.

<template>
 <user-data :firstname="person.firstname" :lastname="person.lastname"></user-data>
</template>
<script>
 export default {
  data() {
   return {
     person: { firstname: 'Max', lastname: 'Schwarz' }
   }
 }
}
</script>
<!--UserData 컴포넌트-->
<template>
 <h2>{{ firstname }} {{ lastname }}</h2>
</template>
<script>
 export default {
  props: ['firstname','lastname']
}
</script>

 

하지만 props로 설정하려는 props를 포함하는 객체가 있는 경우, v-bind를 이용해서 코드를 조금 더 간결하게 작성할 수 있다.

<template>
 <user-data v-bind="person"></user-data>
</template>
<script>
 export default {
  data() {
   return {
     person: { firstname: 'Max', lastname: 'Schwarz' }
   }
 }
}
</script>

v-bind="person"을 사용하면, person 내부의 모든 key-value 쌍을 컴포넌트에 props로 전달 가능하다.

물론 person이 JavaScript 객체여야 한다.

 

이는 순전히 선택사항이지만, 도움이 될 수 있는 작은 편의기능이다.

 

참고:

https://ko.vuejs.org/guide/components/attrs.html#attribute-inheritance

 

폴스루 속성 | Vue.js

 

ko.vuejs.org

** 출처: 모든 내용은 Udemy Vue-완벽가이드 강의, 위 참고페이지를 기반으로 작성하였습니다