内容提要:
- 避免内容更新—keep-alive与动态组件
- 异步加载组件的处理方式
这页假定你已经了解组件基础 Components Basics,如果你不了解组件请先读它。
keep-alive
与动态组件
之前,我们使用is
属性去切换组件在标签栏界面:
<component v-bind:is="currentTabComponent"></component>
当在这些组件中切换组件的时候,有时你想要保持这些组件的状态或为了性能避免重新渲染。例如:当我们展开我们的多标签界面时:
切到Archive Tab:
切换回Posts:
你会注意到,如果你选择一篇文章,切换到Archive栏,然后在切换回Posts,它不在展示你选择的那篇博文了,这是因为每一次你切换到一个新的标签,Vue都会创建一个新的currentTabComponent
实例。
重新创建动态组件在正常状态下是有用的,在这个例子中,我们希望这些tab组件在第一次创建的时候就被缓存。为了解决这个问题,我们能使用元素封装一个动态组件:
<!-- 失活的组件将被缓存 -->
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
切换Archive tab:
切回Posts:
现在Posts标签栏保留了状态(被选择的文章)甚至当它没有被渲染的时候也是如此,完整代码看this fiddle。
注意keep-alive标签元素要求被切换的组件都有自己的名字,或者用name操作符在组件上,或通过本地或全局注册。
关于的详情请参阅API reference。
异步组件
在大型应用程序中,我们需要把应用分割成小块代码,并且仅仅在需要的时候从服务器加载一个组件。为了简化,Vue允许你以一个工厂函数的方式去定义你的组件,这个工厂函数会异步的解析你的组件定义。Vue仅仅会在组件需要被渲染的时候触发工厂方法,并且会缓存渲染的结果以便未来使用,例如:
Vue.component('async-example', function(resolve, reject){
setTimeout(function(){
// 传递组件定义去处理回调
resolve({
template: '<div>I am async</div>'
})
}, 1000)
})
正如你所看到的,工厂方法接收一个resolve
回调。当你从服务器收到组件定义的时候这个回调会被调用。你也可以调用reject(reason)
来表示加载失败。这里setTimeout
是一个演示;如何去检索组件取决于你。一个推荐的实现是和Webpack’s code-splitting feature一起使用异步组件:
Vue.component('async-webpack-example', function(resolve){
// 这个特定的请求语法会通知Webpack把你的构建包自动分为多个包,这些包会通过Ajax加载
require(['./my-async-component'], resolve)
})
你也能够在工厂方法里返回一个Promise
,你能够使用Wepack2和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
用户想要使用一个异步控件,但很不幸的它的开发者明确表示made it clear异步加载“将不被Browserify支持”,至少官方是这样。Browserify社区有了一些变通方案,这些方案对于已经存在的和复杂的应用是有帮助的。对于其他的场景,我们建议使用Webpack去构建,会对内部做很好的支持。
管理加载状态
2.3.0 + 新增
异步组件工厂函数也可以通过以下方式返回一个对象:
const AsycComponent = () => ({
// 需要加载的组件(应该是一个Promise对象)
component: import('./MyComponent.vue'),
// 异步组件加载的时候需要使用的组件
loading: LoadingComponent,
// 加载失败的时候使用的组件
error:ErrorComponent,
// 展示加载组件之前的延迟。默认:200毫秒。
delay:200,
// 如果提供了超时时间且组件加载也被超时了,则使用加载失败是使用的组件。默认值:Infinity
timeout: 3000
})
**注意:**如果你希望使用上面的语法和路由组件你需要使用 Vue Router 2.4.0+以上版本。