Non-prop속성 (fallthrough 속성)
부모 컴포넌트에서 자식요소에 class와 style 속성 그리고 이벤트가 정의되어 있으면, 자식 요소에서는 부모의 class와 style속성 그리고 이벤트와 병합하거나 덮어쓴다.
속성 병합 특성
•
TheView.vue
코드 복사하기
부모요소에 class / style / id 태그 속성이 정의 되어있다고 가정해보자.
•
Labelnput.vue
코드 복사하기
•
확인
부모에서 정의된 속성과 병합된 것을 확인할 수 있다.
❗️❗️ 하지만 class / style을 제외한 id는 덮어쓰기가 되었다.
v-on 이벤트 리스너 상속
자식요소에 이벤트리스너 상속
•
TheView.vue
코드 복사하기
→ 부모요소인 TheView.vue 에서 자식요소의 컴포넌트를 등록하고 @click 이벤트를 등록함
•
MyButton.vue
코드 복사하기
자식요소에는 이벤트리스너가 없어도 부모것을 상속한다.
•
확인
렌더링이 되었을 때 부모의 이벤트가 자식요소에 등록이 되었다.
속성 상속 비활성화
컴포넌트가 non-prop속성을 자동으로 상속받지 않도록 하는 제어문법이다. inheritAttrs: false 옵션을 설정할 수 있다.
•
MyButton.vue
이벤트를 상속받을 때, 이벤트가 자식요소의 루트 엘리먼트에 상속이 되므로, 버튼을 누르지 않다라도 루트엘리먼트가 이벤트를 받게 되는 상황이 발생할 수 있다.
배경을 클릭했는데 이벤트가 발생하는 상황이 생길 수 있다.
그렇다면 이 구조에서 루트엘리먼트가 작동하지 않고 버튼만 작동하게 할수 있을까??
attr 속성과 inheritAtrrs: false
코드 복사하기
→ inheritAttrs: false 로 속성상속을 취소할 수 잇다.
→ 하지만 setup함수의 두 번째 매개변수 context의 내부속성 attrs로 부모의 속성을 가져올 수는 있다.
→ inheritAttrs: false로 상속취소가능
→ context.attrs로 부모속성을 가져올 수 있다.
•
그럼 버튼에 v-bind로 $attrs를 바인딩하면 버튼에만 적용가능하다.
v-bind로 $attrs를 바이딩하여 부모 속성을 원하는 곳에만 바인딩 할 수 있다.
•
확인
이렇게 클릭하면 부모 속성이 버튼에만 전달 되었다.
fragments
vue3는 다중루트 컴포넌트 fragments를 지원한다.
•
LabelInput.vue
코드 복사하기
이렇게 최상위 엘리먼트를 여러개 설정할 수 있는 건 알겠는데,
만약 부모의 속성이 상속이 될 때 그 속성은 어디로 가는 것일까????
•
확인
이걸 해결할려면 명시적으로 상속을 해줘야 된다.
•
해결
위 처럼 다중루트 엘리먼트 환경에서 상속을 해야하는 경우에는
어떤 루트 엘리먼트에 상속을 해야될 지 명시적으로 선언해줘야된다.
non-props 속성 중복이벤트 방지하기
non-props속성에서 따로 명시를 하지 않으면 자식요소의 루트 엘리멘트로 부모의 속성이 상속 된다.
•
MyButton.vue
코드 복사하기
→ 자식요소의 클릭이벤트를 emits로 명시적 선언을 하지 않고 이벤트를 부모로 올려주면 이상한 현상이 발생할 수 잇다.
→ 일단 자식요소에서 명시적 선언을 하지 않으면 해당 속성은 non-props속성으로 부모로부터 다시 받게 되는데, 그때 루트 엘리먼트로 자동 상속이 되게된다.
•
TheView.vue
코드 복사하기
→ 자식에게서 받은 @click 이벤트를 자식컴포넌트에 달았지만,
이 이벤트는 자식요소에서 emits 로 선언되지 않았기 때문에,
해당 이벤트는 non-props속성으로 자식요소에게 다시 전해지게 된다.
•
확인
→ 해당 non-props 이벤트는 자식요소의 버튼으로 바인딩 되지 않고, 버튼을 감싸는 루트 엘리먼트로 상속이 된다.
→ 그래서 버튼을 클릭하게 되면 이벤트가 전파가 되어서 두번 알림이 뜨게 된다.
•
해결
→ 이벤트를 올려줄 때 emits 선언에 등록해줘야지 원치 않게 루트 엘리먼트로 이벤트가 상속이 되어 중복이벤트가 발생하는 불상사가 생기지 않는다. 그러니 항상 emits선언을 해주는 습관을 가지자