Dynamic components & asynchronous components
This page assumes that you have read Component Basics. If you don’t know much about components yet, I recommend you read it first.
Table of contents
Use keep-alive
## on dynamic components
#We have previously used the is attribute to switch different components in a multi-tab interface:
<component v-bind:is="currentTabComponent"></component>When switching between these components, you sometimes want to Maintain the state of these components to avoid performance issues caused by repeated re-rendering. For example, let's expand on this multi-tab interface: You will notice that if you select an article, switch to the
Archive tag , and then switch back to Posts, the articles you selected before will not continue to be displayed. This is because Vue creates a new currentTabComponent instance every time you switch to a new tab.
<keep-alive> element.
<!-- 失活的组件将会被缓存!--> <keep-alive> <component v-bind:is="currentTabComponent"></component> </keep-alive>Let’s take a look at the modified results: Now the Posts tag retains its status (selected post) even when it is not The same goes for rendering. You can check out the complete code in
this fiddle.
Note thisYou can check out more details about<keep-alive>
requires that the component being switched to has its own name, whether through the component's
nameoption or locally /Global registration.
<keep-alive> in the API reference document.
Asynchronous components
#In large applications, we may need to split the application into smaller code blocks and only use them when needed Just load a module from the server. To simplify, Vue allows you to define your component as a factory function, which will parse your component definition asynchronously. Vue will only trigger the factory function when the component needs to be rendered, and cache the results for future re-rendering. For example:
Vue.component('async-example', function (resolve, reject) { setTimeout(function () { // 向 `resolve` 回调传递组件定义 resolve({ template: '<div>I am async!</div>' }) }, 1000) })
As you can see, this factory function will receive a resolve
callback, which will be called when you get the component definition from the server. You can also call reject(reason)
to indicate a loading failure. setTimeout
here is for demonstration purposes. How to obtain the component depends on you. A recommended approach is to use asynchronous components with webpack's code-splitting feature:
Vue.component('async-webpack-example', function (resolve) { // 这个特殊的 `require` 语法将会告诉 webpack // 自动将你的构建代码切割成多个包,这些包 // 会通过 Ajax 请求加载 require(['./my-async-component'], resolve) })
You can also return a Promise
in the factory function, so Adding webpack 2 and ES2015 syntax together, we can write it like this:
Vue.component( 'async-webpack-example', // 这个 `import` 函数会返回一个 `Promise` 对象。 () => import('./my-async-component') )
When using local registration, you can also directly provide a return Promise
Function:
new Vue({ // ... components: { 'my-component': () => import('./my-async-component') } })
If you are a Browserify user who also likes to use asynchronous components, unfortunately the author of this tool clearly stated that asynchronous loading "will not Supported by Browserify", at least not officially. The Browserify community has found some workarounds that may be helpful for existing complex applications. For other scenarios, we recommend using webpack directly to have first-class async support built-in.
Handling loading status
2.3.0 New
The asynchronous component factory function here can also return an object in the following format:
const AsyncComponent = () => ({ // 需要加载的组件 (应该是一个 `Promise` 对象) component: import('./MyComponent.vue'), // 异步组件加载时使用的组件 loading: LoadingComponent, // 加载失败时使用的组件 error: ErrorComponent, // 展示加载时组件的延时时间。默认值是 200 (毫秒) delay: 200, // 如果提供了超时时间且组件加载也超时了, // 则使用加载失败时使用的组件。默认值是:`Infinity` timeout: 3000 })
Note: If you want to use Vue If you use the above syntax in the routing component of Router, you must use Vue Router 2.4.0 version.