동적 구성 요소 및 비동기 구성 요소


이 페이지에서는 구성 요소 기본 사항을 읽었다고 가정합니다. 아직 컴포넌트에 대해 잘 모르신다면 먼저 읽어보시길 권합니다.


Directory


동적 구성요소에 keep-alivekeep-alive


我们之前曾经在一个多标签的界面中使用 is 特性来切换不同的组件:

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

当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。例如我们来展开说一说这个多标签界面:

1.gif

你会注意到,如果你选择了一篇文章,切换到 Archive 标签,然后再切换回 Posts,是不会继续展示你之前选择的文章的。这是因为你每次切换新标签的时候,Vue 都创建了一个新的 currentTabComponent 实例。

重新创建动态组件的行为通常是非常有用的,但是在这个案例中,我们更希望那些标签的组件实例能够被在它们第一次被创建的时候缓存下来。为了解决这个问题,我们可以用一个 <keep-alive> 元素将其动态组件包裹起来。

<!-- 失活的组件将会被缓存!-->
<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

来看看修改后的结果:

2.gif

现在这个 Posts 标签保持了它的状态 (被选中的文章) 甚至当它未被渲染时也是如此。你可以在这个 fiddle 查阅到完整的代码。

注意这个 <keep-alive> 要求被切换到的组件都有自己的名字,不论是通过组件的 name 选项还是局部/全局注册。

你可以在 API 参考文档 查阅更多关于 <keep-alive>


를 사용하세요. 이전에는 다중 탭 인터페이스에서 다른 구성요소를 전환하기 위해 is 속성을 사용했습니다.


Vue.component('async-example', function (resolve, reject) {
  setTimeout(function () {
    // 向 `resolve` 回调传递组件定义
    resolve({
      template: '<div>I am async!</div>'
    })
  }, 1000)
})

이러한 구성 요소 간에 전환할 때 반복적인 다시 렌더링으로 인해 발생하는 성능 문제를 방지하기 위해 이러한 구성 요소의 상태를 유지하려는 경우가 있습니다. 예를 들어 멀티탭 인터페이스를 확장하여 이야기해 보겠습니다. 🎜🎜1.gif🎜🎜기사를 선택하면 보관 태그로 전환한 다음 다시 게시물으로 전환하는 것을 볼 수 있습니다. 예 이전에 선택한 기사는 더 이상 표시되지 않습니다. 이는 새 탭으로 전환할 때마다 Vue가 새로운 currentTabComponent 인스턴스를 생성하기 때문입니다. 🎜🎜동적 구성 요소의 동작을 재현하는 것은 종종 매우 유용하지만, 이 경우 해당 태그의 구성 요소 인스턴스가 처음 생성될 때 캐시되는 것을 선호합니다. 이 문제를 해결하기 위해 동적 구성 요소를 <keep-alive> 요소로 래핑할 수 있습니다. 🎜
Vue.component('async-webpack-example', function (resolve) {
  // 这个特殊的 `require` 语法将会告诉 webpack
  // 自动将你的构建代码切割成多个包,这些包
  // 会通过 Ajax 请求加载
  require(['./my-async-component'], resolve)
})
🎜수정된 결과를 살펴보겠습니다. 🎜🎜2.gif🎜🎜이제 Posts 태그는 렌더링되지 않더라도 상태(선택한 게시물)를 유지합니다. 이 바이올린🎜에서 전체 코드를 확인할 수 있습니다. 🎜🎜🎜 <keep-alive>에서는 전환되는 구성 요소가 구성 요소의 name 옵션을 통해서든 로컬/전역 등록을 통해서든 고유한 이름을 가져야 한다는 점에 유의하세요. 🎜🎜🎜API 참조 문서🎜에서 <keep에 대해 자세히 알아볼 수 있습니다. -살아있다> 세부정보. 🎜🎜🎜🎜

Asynchronous Components


대규모 애플리케이션에서는 애플리케이션을 더 작은 코드 덩어리로 분할하고 필요할 때만 서버에서 모듈을 로드해야 할 수도 있습니다. 단순화하기 위해 Vue를 사용하면 구성 요소 정의를 비동기식으로 구문 분석하는 팩토리 함수로 구성 요소를 정의할 수 있습니다. Vue는 구성 요소를 렌더링해야 할 때만 이 팩토리 기능을 트리거하고 향후 다시 렌더링을 위해 결과를 캐시합니다. 예:

Vue.component(
  'async-webpack-example',
  // 这个 `import` 函数会返回一个 `Promise` 对象。
  () => import('./my-async-component')
)

보시다시피 이 팩토리 함수는 서버에서 구성 요소 정의를 가져올 때 호출되는 resolve 콜백을 수신합니다. reject(reason)을 호출하여 로드 실패를 나타낼 수도 있습니다. 여기의 setTimeout은 데모용입니다. 구성 요소를 얻는 방법은 귀하에게 달려 있습니다. 권장되는 접근 방식은 webpack의 코드 분할 기능 resolve 回调,这个回调函数会在你从服务器得到组件定义的时候被调用。你也可以调用 reject(reason) 来表示加载失败。这里的 setTimeout 是为了演示用的,如何获取组件取决于你自己。一个推荐的做法是将异步组件和 webpack 的 code-splitting 功能一起配合使用:

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

你也可以在工厂函数中返回一个 Promise,所以把 webpack 2 和 ES2015 语法加在一起,我们可以写成这样:

const AsyncComponent = () => ({
  // 需要加载的组件 (应该是一个 `Promise` 对象)
  component: import('./MyComponent.vue'),
  // 异步组件加载时使用的组件
  loading: LoadingComponent,
  // 加载失败时使用的组件
  error: ErrorComponent,
  // 展示加载时组件的延时时间。默认值是 200 (毫秒)
  delay: 200,
  // 如果提供了超时时间且组件加载也超时了,
  // 则使用加载失败时使用的组件。默认值是:`Infinity`
  timeout: 3000
})

当使用局部注册的时候,你也可以直接提供一个返回 Promise과 함께 비동기 구성 요소를 사용하는 것입니다.

rrreee
다음과 같이 할 수도 있습니다. 팩토리 함수에서 Promise를 반환하므로 webpack 2와 ES2015 구문을 함께 추가하면 다음과 같이 작성할 수 있습니다. .html#partial-registration" target="_blank">

부분 등록 시 Promise를 반환하는 함수를 직접 제공할 수도 있습니다. rrreee Browserify 사용자인 경우 불행히도 이 도구의 작성자는 적어도 공식적으로는 비동기 로딩이 "Browserify에서 지원되지 않을 것"이라고 분명히 밝혔습니다. Browserify 커뮤니티는 기존의 복잡한 애플리케이션에 도움이 될 수 있는

몇 가지 해결 방법
을 찾았습니다. 다른 시나리오의 경우 webpack을 직접 사용하여 최고 수준의 비동기 지원 기능을 내장하는 것이 좋습니다.


로드 상태 처리

2.3.0+ New

여기서 비동기 구성 요소 팩토리 함수는 다음 형식으로 개체를 반환할 수도 있습니다.

Vue Router의 라우팅 구성 요소에서 위 구문을 사용하는 경우 Vue Router 2.4.0+ 버전을 사용해야 합니다.