<template>
<button>
<slot></slot>
</button>
</template>
<script>export default {}</script>
<base-button type="submit" @click="doSomething">Click me</base-button>
Vue에는 "fallThrough" property(event) 지원이 내장되어 있기 때문이다.
즉, 커스텀 컴포넌트 태그에 추가된 property 및 event는 자동으로 해당 컴포넌트의 템플릿에 있는 root 컴포넌트로 넘어간다.
그럼 App.vue 에서 사용된 속성값들이 BaseButton의 <button>속으로 자동으로 들어간다는 것이다.
내장된 $attrs
property(예: this.$attrs)에서 이러한 fallThrough property 에 액세스할 수 있다.
이것은 모든 프로퍼티와 이벤트를 개별적으로 정의하고 싶지 않은 "유틸리티" 컴포넌트 또는 순수한 프리젠테이션 컴포넌트를 구축하는 데 편리할 수 있다.
만약 위와같이 있을 때 App.vue => Knowledge-element.vue 까지 props을 넘길 때 무수히 많은 불필요한 코드를 넣어야한다. 이를 react에서는 props drilling이라고 하였다. 이를 이를 방지하고자 context API, redux등을 이용하여 props(state)를 관리하였다.
그리고 vue는 이러한 props drilling을 막고자 provide, inject라는 특수 속성이 존재한다.
한 곳에 데이터를 제공하고 삽입, 즉 해당 데이터를 다른 곳에서 사용하는 데 사용할 수 있는 패턴이다.
하지만 단점으로는 역시 provide와 inject사이에 어떠한 데이터가 움직이는 코드가 없다보니 처음 본 사람은 이것을 일일이 찾아봐야한다는 단점이 있다.
<script>
privide(){
return{
속성이름 : this.속성이름
속성이름 : this.메서드이름
}
},
</script>
<script>
export default {
inject:[
'provide에서 작성한 속성값'
],
methods:{
어떠한메서드(){
this.메서드이름()
}
}
};
</script>
<knowledge-base :topics="topics" @select-topic="activateTopic"></knowledge-base>
<knowledge-base></knowledge-base>
<template>
<li>
<h3>{{ topicName }}</h3>
<p>{{ description }}</p>
<button @click="$emit('select-topic', id)">Learn More</button>
</li>
</template>
<script>
export default {
props: ['id', 'topicName', 'description'],
emits: ['select-topic'],
};
</script>
<template>
<li>
<h3>{{ topicName }}</h3>
<p>{{ description }}</p>
<button @click="selectTopic">Learn More</button>
</li>
</template>
<script>
export default {
inject:['selectTopic'],
props: ['id', 'topicName', 'description'],
emits: ['select-topic'],
};
</script>
selectTopic
은 함수이다. 클릭이 발생하면 실행되는 함수인 것이다....
<script>
provide(){
return{
topics:this.topics,
selectTopic : this.activateTopic
}
},
methods: {
activateTopic(topicId) {
this.activeTopic = this.topics.find((topic) => topic.id === topicId);
},
},
</script>
()
하는 것이 아닌 pointing만 해 주는 것, 안내만 해주는 것이다.provide/inject 기능의 원리 때문에 그렇다.
provide 메서드에 객체가 포함되어 있는데 이에 Vue가 provide 메서드를 실행하여 해당 컴포넌트를 생성한다.
이후 inject를 통해 provide의 속성의 배열을 리소스가 필요한 모든 컴포넌트에 삽입한다.
이는 배열이므로 그 값이 메모리에 저장되는데 JavaScript의 참조 값이다.
리소스를 추가할 때와 같이 push나 unshift를 통해서 배열을 변경한다고 하면 기존에 입력했던 메모리 내 동일한 배열에도 변경 사항이 반영된다. 이에 따라 Vue가 해당 변경 사항을 인식할 수 있는 것이다. 그리고 이 resources 키가 삽입된 모든 위치도 이 변경 사항을 인식하게 된다.
반면 filter를 사용하면 배열시 새로 생기고 이 새로운 배열은 다른 모든 컴포넌트에는 입력되지 않는다.
그럼 어떻게 하면 좋을까?
인수로 식별자를 받은 다음 해당하는 index를 찾아 바꿔주는 방식을 선택하면 된다.
메서드(식발자){
const resIndex = this.속성값.findIndex(res => res.id === 식별자);
this.속성값.splice(resIndex, 1)
}