|
总结
引入用于定义异步组件的专用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异步组件。在这种情况下,将需要手动升级,但是这种升级相对较少。
程序猿的技术大观园:www.javathinker.net
|
|