- Start Date: 2020-03-25
- Target Major Version: 3.x
- Reference Issues: https://github.com/vuejs/rfcs/pull/28
总结
引入用于定义异步组件的专用API。
示例
import { defineAsyncComponent } from "vue"
// simple usage
const AsyncFoo = defineAsyncComponent(() => import("./Foo.vue"))
// with options
const AsyncFooWithOptions = defineAsyncComponent({
loader: () => import("./Foo.vue"),
loadingComponent: LoadingComponent,
errorComponent: ErrorComponent,
delay: 200,
timeout: 3000
})
动机
根据RFC-0008:渲染功能API更改中引入的更改,现在在Vue 3中将普通功能视为功能组件。现在必须通过API方法显式定义异步组件。
详细设计
简单用法
import { defineAsyncComponent } from "vue"
// simple usage
const AsyncFoo = defineAsyncComponent(() => import("./Foo.vue"))
defineAsyncComponent 可以接受一个返回一个解析为实际组件的Promise的加载函数.
- 如果返回值是一个ES模块, 那么 模块的
默认导出将被自动认为是组件。 - 与2.x的区别:请注意,加载器函数不再像2.x中那样接收
resolve和reject参数-必须始终返回Promise。
对于依赖于自定义resolve并且reject在加载程序函数中的代码,转换非常简单:
// before
const Foo = (resolve, reject) => {
/* ... */
}
// after
const Foo = defineAsyncComponent(() => new Promise((resolve, reject) => {
/* ... */
}))
可选项
import { defineAsyncComponent } from "vue"
const AsyncFooWithOptions = defineAsyncComponent({
loader: () => import("./Foo.vue"),
loadingComponent: LoadingComponent,
errorComponent: ErrorComponent,
delay: 100, // default: 200
timeout: 3000, // default: Infinity
suspensible: false, // default: true
onError(error, retry, fail, attempts) {
if (error.message.match(/fetch/) && attempts <= 3) {
retry()
} else {
fail()
}
}
})
delay和timeout选项和2.0版本表现完全一致
与2.x的区别:
component选项已经被新的loader选项代替, 新的loader选项接受和以上示例用法同样的加载函数。
在2.x版本中,一个带有选项的异步组件被这样定义
() => ({ component: Promise<Component> // ...other options })
///在3.0版本中
defineAsyncComponent({ loader: () => Promise<Component> // ...other options })
- 2.x版本中的
loading和error选项已经被重命名为loadingComponent和errorComponent以便更加精确的描述行为。
重试控制
全新的 onError 选项提供了一个Hook在加载出错时进行自定义的重试操作
const Foo = defineAsyncComponent({
// ...
onError(error, retry, fail, attempts) {
if (error.message.match(/fetch/) && attempts <= 3) {
// retry on fetch errors, 3 max attempts
retry()
} else {
fail()
}
}
})
需要注意点是retry/fail 和Promise中的resolve/reject 非常类似:他们的其中之一必须被调用才能继续进行处理。
和<Suspense>一起使用
默认情况下,3.x版本的异步组件是可暂停的。这意味着如果一个异步组件的父元素链中有一个 <Suspense> , 这个异步组件将会被视为该<Suspense>的一个异步依赖项。 在那种情况下, 加载状态将会被 <Suspense>控制,组件自身的 loading, error, delay 和timeout选项将会被无视。
异步组件也可以通过在选项中标明suspensible: false来退出默认的<Suspense>控制,始终自行控制其加载状态。
采纳策略
- 语法转换是机械性的,可以通过代码被执行。挑战在于确定哪些简单功能应被视为异步组件。可以使用一些基本的方法:
- 返回对于
.vue文件的动态import调用的箭头函数 - 返回一个拥有一个动态
import调用作为自己component属性的对象的箭头函数
- 返回对于
请注意,这可能没办法完全覆盖目前的使用。
- 在兼容版本中中,可以检查功能组件的返回值并警告旧版异步组件使用情况。这应该涵盖所有基于Promise的用例。
- 唯一无法轻易检测到的情况是使用手动
resolve/reject而不是返回Promise的2.x异步组件。在这种情况下,将需要手动升级,但是这种升级相对较少。
其他RFC
达瓦里希:Vue 3新特性RFC列表(翻译尚未完成)zhuanlan.zhihu.com
介绍了Vue 3中异步组件的新API——defineAsyncComponent的使用方法及与Vue 2的区别,包括简单的用法、配置选项如加载、错误处理等。
898

被折叠的 条评论
为什么被折叠?



