指南
基础概要
- 安装
- 介绍
- Vue 实例
- 模板语法
- computed 属性和 watcher
- class 和 style 绑定
- 根据条件进行渲染
- 列表渲染
- 事件处理
- 表单 input 绑定
- 组件基础
过渡 & 动画
- 进入、离开和列表的过渡
深入组件
- 组件注册
- props
- 自定义事件
- slot
- 动态组件和异步组件
- Handling Edge Cases
- 状态间的过渡
可重用 & 合成
- mixin
- 自定义指令
- render 函数 & jsx
- 插件
- 过滤器
工具
- 生产环境部署
- 单文件组件
- 单元测试
- TypeScript 支持
扩展升级
- 路由
- 状态管理
- 服务端渲染
内部原理
- 深入响应式原理
升级迁移
- 从 Vue 1.x 迁移
- 从 Vue Router 0.7.x 迁移
- 从 Vuex 0.6.x 迁移到 1.0
其他更多
- 对比其他框架
- 加入 Vue.js 社区
- 认识团队
动态组件和异步组件
本页面会假定你已经阅读过 组件基础。如果你还不熟悉组件,请先阅读组件基础后再阅读本页面。
对动态组件使用 keep-alive
前面,我们使用 is
特性,在标签页式界面中切换组件:
<component v-bind:is="currentTabComponent"></component> |
有时在这些组件之间切换,需要保留切换前的状态,或者需要考虑重新渲染造成的性能问题,而尽量避免重新渲染。举例说明,稍微扩展下我们的标签页式界面:
然后你会注意到,如果选中某篇文章(post),切换到 Archive 标签页,再切换回 Posts 标签页,而选取的文章则不会再次展现。这是因为,每次你切换到一个新的标签页后,Vue 都会创建 currentTabComponent
所对应组件的一个全新实例。
重新创建动态组件是一种常规用法,但是在这个场景中,我们确实希望这些标签页组件的实例,在第一次创建之后就缓存起来。为了解决这个问题,我们可以使用一个 <keep-alive>
元素将动态组件包裹起来:
<!-- Inactive components will be cached! --> |
查看下面结果:
现在 Posts 标签页并未渲染,而是保持它先前(选中那篇文章)的状态。完整代码请查看 fiddle。
注意,<keep-alive>
要求被切换的组件都要具有 name,要么是使用组件的 name
选项,要么就是通过局部/全局注册。
更多细节请查看 API 参考 中 <keep-alive>
部分。
异步组件
在大型应用程序中,我们可能需要将应用程序拆分为多个小的分块(chunk),并且只在实际用到时,才从服务器加载某个组件。为了简化异步按需加载组件机制,Vue 能够将组件定义为一个工厂函数(factory function),此函数可以异步地解析(resolve)组件定义对象(component definition)。Vue 只在真正需要渲染组件时,才会去触发工厂函数,并且将解析后的结果缓存,用于将来再次渲染。例如:
Vue.component('async-example', function (resolve, reject) { |
就像你看到的那样,工厂函数接收一个 resolve
回调函数,在从服务器获取到组件定义对象时,会调用此回调函数。也可以调用 reject(reason)
来表明加载失败。这里的 setTimeout
只是为了用于演示;如果获取组件定义对象,取决于你的实际情况。使用异步组件,比较推荐的方式是配合 webpack 代码分离功能
Vue.component('async-webpack-example', function (resolve) { |
还可以在工厂函数中返回一个 Promise
,所以配合 webpack 2 + ES2015 语法,你可以这样实现:
Vue.component( |
当使用 局部注册 时,你也可以直接提供一个返回 Promise
的函数:
new Vue({ |
如果你是想要使用异步组件的 Browserify 用户,不幸的是,它的作者已经 明确表示 Browserify 是不支持异步加载的。虽然官方如此表示,然而 Browserify 社区还是找到 一些解决方案,这可能有助于现有的复杂应用程序实现异步组件。对于所有其他场景,我们推荐使用 webpack 内置和优先支持的异步支持。
处理加载状态
2.3.0+ 新增
异步组件工厂函数,还可以返回一个以下格式的对象:
const AsyncComponent = () => ({ |
注意,如果你想要在路由组件中使用以上语法,必须使用 Vue Router 2.4.0+ 版本。