-
Notifications
You must be signed in to change notification settings - Fork 0
Vue Component
- 뷰와 데이터 로직의 재사용
- 반응적이고 조합이 가능한 컴포넌트
- 부모-자식 컴포넌트 간의 명확한 인터페이스 분리
- 추론이 쉽고 유지 관리가 쉬운 의사소통
- 추론이 쉽게 명확한 콘텐츠 배포 프로세스
- DOM 변경 단일화(refs 객체 사용)
- 인터페이스의 단순화 : Vue 인스턴스를 사용하여
모든 옵션 객체
,라이프 사이클 훅
를 사용할 수 있다.
세 개의 컴포넌트 인스턴스가 모두 같은 data
객체를 공유하므로 하나의 카운터를 증가 시키면 모두 증가합니다.
그래서 새로운 데이터 객체
를 반환하여 이 문제를 해결합니다.
Vue.component('my-component', {
template: '<span>{{ message }}</span>',
data: {message: 'hello'}
})
<div id="example-2">
<simple-counter></simple-counter>
<simple-counter></simple-counter>
<simple-counter></simple-counter>
</div>
컴포넌트는 부모-자식 관계에서 가장 일반적으로 함께 사용하기 위한 것이다. 컴포넌트 A는 자체 템플릿에서 컴포넌트 B를 사용할 수 있다.
그들은 필연적으로 서로 의사소통
이 필요합니다. 부모는 자식에세 데이터를 전달
해야 할 수도 있으며, 자식은 자신에게 일어난 일을 부모에게 알릴 필요
가 있습니다.
그러나 부모와 자식이 명확하게 정의된 인터페이스를 통해 가능한한 분리된 상태
로 유지하는 것도 매우 중요합니다.
이렇게하면 각 컴포넌트의 코드를 상대적으로 격리
할 수 있도록 작성하고 추론
할 수 있으므로 유지 관리가 쉽고
잠재적으로 쉽게 재사용
할 수 있습니다.
VueJs에서 부모-자식 컴포넌트 관계는 props
는 아래로, events
위로 라고 요약할 수 있습니다. 부모는 props
를 통해 자식에게 데이터를 전달하고 자식은 events
를 통해 부모에게 메시지를 보냅니다.
모든 컴포넌트 인스턴스에는 자체 격리 범위
가 있습니다. 즉, 하위 컴포넌트의 템플릿에서 상위 데이터를 직접 참조 할 수 없으며
그렇게 해서는 안됩니다. 데이터를 props
을 사용하여 하위 컴포넌트로 전달 될 수 있습니다.
prop
는 상위 컴포넌트의 정보를 전달하기 위한 사용자 지정 특성입니다. 하위 컴포넌트는 props
옵션을 사용하여
수신 할 것으로 기대되는 props
를 명시적으로 선언해야 합니다.
데이터가 상위에서 업데이트 될 때마다 하위 데이터로도 전달됩니다.
하위 속성과 상위 속성 사이의 단방향 바인딩
을 형성합니다. 상위 속성이 업데이트되면 하위로 흐르게 되지만 그 반대는 안됩니다.
이렇게하면 하위 컴포넌트가 실수로 부모의 상태를 변경하여 앱의 데이터 흐름을 추론하기 더 어렵게 만드는 것을 방지
할 수 있습니다.
대부분의 속성의 경우 컴포넌트에 제공된 값은 컴포넌트에서 설정된 값을 대체합니다. 예를 들어, type="large"
가 전달되면
type="data"
를 대체할 것이고 아마도 망가뜨릴 것입니다. class
와 style
속성은 두 값이 합쳐져서 최종 값으로 만듭니다.
부모 컴포넌트는 자식 컴포넌트가 사용되는 템플릿에서 직접 v-on
을 사용하여 자식 컴포넌트에서 보내진 이벤트를 청취할 수 있습니다.
부모-자식이 아닌 두 컴포넌트가 서로 통신이 필요할 때 Vue 인스턴스를 중앙 이벤트 버스로 사용할 수 있습니다.
var bus = new Vue()
// 컴포넌트 A의 메소드
bus.$emit('id-selected', 1)
// 컴포넌트 B의 created 훅
bus.$on('id-selected', function (id) {
// ...
})
컴포넌트를 사용할 때 다음과 같이 컴포넌트를 구성하는 것이 좋습니다.
<app>
<app-header></app-header>
<app-footer></app-footer>
</app>
주목해야할 두가지 사항이 있습니다.
-
<app>
컴포넌트는 어떤 컨텐츠를 받을 지 모릅니다. 그것은<app>
이 사용하는 컴포넌트에 의해 결정됩니다. -
<app>
컴포넌트에는 자체 템플릿이 있을 가능성이 큽니다.
위 구성으로 작동하도록 하려면 부모 콘텐츠와 컴포넌트의 자체의 템플릿을 섞는 방법이 필요합니다. 이것은 콘텐츠 배포 프로세스
입니다.
VueJS는 현재 웹 컴포넌트 사양 초안을
모델로 한 콘텐츠 배포 API를 구현하며 원본 콘텐츠의 배포판 역할 하기 위해 특수한 <slot>
엘리먼트를 사용합니다.
컴파일되는 범위를 명확히 해야 합니다. 다음과 같은 템플릿이 있다고 상상해보겠습니다.
<child-component>{{message}}</child-component>
message
가 부모 데이터 또는 자식 데이터 중 부모에 바인딩되어야 합니다. 컴포넌트 범위에 대한 간단한 법칙은 다음과 같습니다.
- 상위 템플릿의 모든 내용은 상위 범위로 컴파일됩니다.
- 하위 템플릿의 모든 내용은 하위 범위에서 컴파일됩니다.
일반적인 실수는 부모 템플릿의 하위 속성/메소드에 디렉티브를 바인딩하려고하는 것입니다.
<child-component v-show="someChildProperty"></child-component>
someChildProperty
가 자식 컴포넌트의 속성이라고 가정하면, 위의 예제는 작동하지 않을 것입니다.
하위 컴포넌트 템플릿에 최소한 하나의 <slot>
콘텐츠가 포함되어 있지 않으면 부모 콘텐츠가 삭제 됩니다.
속성이 없는 슬롯이 하나 뿐인 경우 전체 내용 조각이 DOM의 해당 위치에 삽입되어 슬롯 자체를 대체합니다.
원래 <slot>
태그 안에 있는 내용은 대체 콘텐츠
로 간주됩니다. 대체 콘텐츠는 하위 범위에서 컴파일 되며 호스팅 엘리먼트가 비어 있고
삽입할 콘텐츠가 없는 경우에만 표시됩니다.
my-component
라는 컴포넌트가 있다고 가정
<div>
<h2>나는 자식 컴포넌트의 제목입니다</h2>
<slot>
제공된 컨텐츠가 없는 경우에만 보실 수 있습니다.
</slot>
</div>
컴포넌트를 사용하는 부모 컴포넌트
<div>
<h1>나는 부모 컴포넌트의 제목입니다</h1>
<my-component>
<p>이것은 원본 컨텐츠 입니다.</p>
<p>이것은 원본 중 추가 컨텐츠 입니다</p>
</my-component>
</div>
아래처럼 렌더링 됩니다.
<div>
<h1>나는 부모 컴포넌트의 제목입니다</h1>
<div>
<h2>나는 자식 컴포넌트의 제목 입니다</h2>
<p>이것은 원본 컨텐츠 입니다.</p>
<p>이것은 원본 중 추가 컨텐츠 입니다</p>
</div>
</div>
슬롯의 이름을 지정하여 어떻게 내용을 배포해야 하는 지를 커스터마이징을 할 수 있다. 명명되지 않은 슬롯은 하나만 사용되고 콘텐츠의 포괄적인 컨텐츠 역할을 합니다.
어려워서 작성안함...
같은 마운트 포인트를 사용하고 예약된 <component>
엘리먼트를 사용하여 어러 컴포넌트 간의 동적으로 트랜지션하고
is
속성에 동적으로 바인드 할 수 있습니다.
var vm = new Vue({
el: '#example',
data: {
currentView: 'home'
},
components: {
home: { /* ... */ },
posts: { /* ... */ },
archive: { /* ... */ }
}
})
<component v-bind:is="currentView">
<!-- vm.currentView가 변경되면 컴포넌트가 변경됩니다! -->
</component>
컴포넌트를 작성할 때 나중에 다른 곳에서 다시 사용할 것인지에 대한 여부를 명심하는 것이 좋습니다.
일회용 컴포넌트가 단단히 결합 되어도 상관 없지만 재사용 가능한 컴포넌트는 깨끗한 공용 인터페이스를 정의 해야하며
사용된 컨텍스트에 대한 가정을 하지 않아야합니다.
Vue 컴포넌트의 API는 Props
, Event
, Slot
의 세 부분으로 나뉩니다.
-
Props
는 외부 환경이 데이터를 컴포넌트로 전달하도록 허용합니다. -
Event
를 통해 컴포넌트가 외부 환경에서 사이드 이펙트를 발생할 수 있도록 합니다. -
Slot
을 사용하면 외부 환경에서 추가 컨텐츠가 포함 된 컴포넌트를 작성할 수 있습니다.
props
나 event
가 있었음에도 불구하고 때때로 Javascript로 하위 컴포넌트에 직접 액세스 해야 할 수도 있습니다.
이를 위해 ref
를 사용하여 참조 컴포넌트 ID를 자식 컴포넌트에 할당해야 합니다.
ref
는 엘리먼트 또는 자식 컴포넌트에 대한 참조를 등록
하는 데 사용합니다. 일반 DOM 엘리먼트에 사용되는 경우
참조는 해당 엘리먼트입니다. 하위 컴포넌트에서 사용되는 경우 참조는 컴포넌트 인스턴스입니다.
참조 자체는 렌더링 함수의 결과
로 생성되기 때문에 초기 렌더링에서 참조 자체를 엑세스 할 수 없습니다. 그리고
반응이 없으므로 데이터 바인딩을 위해 템플릿에서 사용해서는 안됩니다.
대규모 응용 프로그램에서 응용 프로그램을 더 작은 덩어리로 나누고 실제로 필요할 때만 서버에서 컴포넌트를 로드해야 할 수도 있습니다.
Vue를 사용하면 컴포넌트 정의를 비동기식으로 해결하는 팩토리 함수
로 컴포넌트를 정의 할 수 있습니다. Vue는 컴포넌트가 실제로 렌더링되어야 할 때만 팩토리 기능을 트리거하고 이후의 리렌더링을 위해 결과를 캐시
합니다.
Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
// 컴포넌트 정의를 resolve 콜백에 전달합니다.
resolve({
template: '<div>I am async!</div>'
})
}, 1000)
})
일반 HTML 엘리먼트를 렌더링하는 것은 Vue에서 매우 빠르지만 가끔 정적 콘텐츠가 많이
포함된 컴포넌트가 있을 수 있습니다.
이런 경우, v-once
디렉티브를 루트 엘리먼트에 추가함으로써 캐시가 한번만
실행되도록 할 수 있습니다.
Vue.component('terms-of-service', {
template: '\
<div v-once>\
<h1>Terms of Service</h1>\
... a lot of static content ...\
</div>\
'
})