동적 & 비동기 컴포넌트

이 페이지는 여러분이 이미 컴포넌트 기초를 읽었다고 가정하고 쓴 내용입니다. 컴포넌트가 처음이라면 기초 문서를 먼저 읽으시기 바랍니다.

keep-alive 동적 컴포넌트

초기에는, 탭 인터페이스에서 컴포넌트들을 전환하기 위해서 is 특성을 사용했습니다. :

<component v-bind:is="currentTabComponent"></component>

컴포넌트들을 전환할 때 가끔 성능상의 이유로 상태를 유지하거나 재-렌더링을 피하길 원할 수 있습니다. 예를 들면, 탭 인터페이스를 약간 확장 할 때 :

게시물을 선택하고, Archive 탭으로 전환하고, 다시 Posts로 전환할 때, 선택했던 게시물이 더는 보이지 않는 것 알아차릴 수 있습니다. 그 이유는 매번 새로운 탭을 선택할 때, Vue는 currentTabComponent의 새로운 인스턴스를 생성하기 때문입니다.

동적 컴포넌트를 재생성하는 것은 보통은 유용한 동작입니다. 하지만 이 경우에는, 탭 컴포넌트 인스턴스가 처음 생성될 때 캐시 되는 것을 선호합니다. 이런 문제를 해결하기 위해서, 동적 컴포넌트를 <keep-alive> 엘리먼트로 둘러쌀 수 있습니다. :

<!-- Inactive components will be cached! -->
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>

아래 결과를 확인하세요. :

이제 Posts 탭은 (게시물이 선택된) 상태를 유지할 수 있고 다시 렌더링하지도 않습니다. 완성된 코드는 this fiddle에서 볼 수 있습니다.

``가 컴포넌트에서 `name` 옵션을 사용하거나 로컬/글로벌 등록을 하여 정의된 모든 것들로 전환되고 있는 컴포넌트들을 요구한다는 것에 유의하세요.

더 자세한 내용은 API reference에서 <keep-alive> 항목을 확인해주세요.

비동기 컴포넌트

커다란 어플리케이션의 경우, 앱을 작은 조각들로 나누어 두고 필요한 경우에만 서버로부터 필요한 컴포넌트를 로드해야 할 수 있습니다. 이런 작업을 쉽게 할 수 있도록 Vue는 팩토리 함수를 이용해 컴포넌트를 비동기적으로 정의하는 것을 허용합니다. Vue는 컴포넌트가 필요할 때 팩토리 함수를 실행하고 미래를 위해 결과를 캐시합니다. 예를 들어:
Vue.component("async-example", function(resolve, reject) {
setTimeout(function() {
// 컴포넌트 정의를 resolve 콜백을 통해 전달
resolve({
template: "<div>I am async!</div>"
});
}, 1000);
});

위의 예에서 보다시피 팩토리 함수는 resolve 콜백을 받습니다. 콜백은 서버에 컴포넌트의 정의를 요청했을 때 호출됩니다. 물론 reject(reason) 을 호출하여 로딩이 실패한 경우에 대응할 수도 있습니다. setTimeout은 예제일 뿐이며, 컴포넌트를 어떻게 받아올지는 원하는 방식을 선택하면 됩니다. 권장되는 접근 방식으로써, Webpack’s code-splitting feature 와 함께 비동기 컴포넌트를 사용하는 패턴이 있습니다:

Vue.component("async-webpack-example", function(resolve) {
// 아래의 특별한 'require' 문법은
// 웹팩이 Ajax를 통해 로드한 번들들을 이용해
// 코드를 자동으로 분할하도록 합니다.
require(["./my-async-component"], resolve);
});

팩토리 함수 안에서 Promise를 반환할 수도 있습니다. Webpack 2와 ES2015 문법을 이용해 아래와 같이 쓸 수 있습니다:

Vue.component(
"async-webpack-example",
// `import` 함수는 Promise를 반환합니다.
() => import("./my-async-component")
);

local registration을 이용하면, Promise를 반환하는 함수를 직접 작성할 수도 있습니다:

new Vue({
// ...
components: {
"my-component": () => import("./my-async-component")
}
});

만약에 Browserify를 이용해서 비동기 컴포넌트를 구현하고자 하는 경우, 불행히도 Browserify를 만든 개발자가 "비동기 컴포넌트는 Browserify가 지원할 계회기 전혀 없는 것이다" 라고 이야기했다는 사실을 알아야 합니다. ([made it clear](https://github.com/substack/node-browserify/issues/58#issuecomment-21978224))
Browserify 커뮤니티는 이미 존재하는 복잡한 예제에 대한 [대안](https://github.com/vuejs/vuejs.org/issues/620)을 찾긴 했습니다. 가능한 모든 시나리오에 대해 비동기를 완벽히 지원하는 웹팩을 이용하는 것을 권장합니다.

Handling Loading State

2.3.0+ 에서 추가

비동기 컴포넌트 팩토리는 아래와 같은 포맷으로 오브젝트를 반환할 수도 있습니다:

const AsyncComponent = () => ({
// 로드 할 컴포넌트(Promise여야 합니다.)
component: import("./MyComponent.vue"),
// 비동기 컴포넌트가 로딩중일 때 사용할 컴포넌트
loading: LoadingComponent,
// 비동기 컴포넌트 로딩이 실패했을 때 사용할 컴포넌트
error: ErrorComponent,
// 로딩 컴포넌트를 보여주기 전의 지연시간. (기본값: 200ms)
delay: 200,
// 초과되었을 때 에러 컴포넌트를 표시할 타임아웃. (기본값: 무한대)
timeout: 3000
});

위에 작성된 문법을 라우터 컴포넌트에 사용하기 위해서는 2.4.0+ 버전의 Vue Router 를 사용해야 한다는 것을 기억하세요!