com组件 异步event_Vue 3新特性RFC-0026异步组件的全新API

介绍了Vue 3中异步组件的新API——defineAsyncComponent的使用方法及与Vue 2的区别,包括简单的用法、配置选项如加载、错误处理等。
  • 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中那样接收resolvereject参数-必须始终返回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()
    }
  }
})
  • delaytimeout 选项和2.0版本表现完全一致

与2.x的区别:

  • component 选项已经被新的loader 选项代替, 新的loader选项接受和以上示例用法同样的加载函数。
    在2.x版本中,一个带有选项的异步组件被这样定义
() => ({ component: Promise<Component> // ...other options })

///在3.0版本中

defineAsyncComponent({ loader: () => Promise<Component> // ...other options })
  • 2.x版本中的 loadingerror 选项已经被重命名为loadingComponenterrorComponent 以便更加精确的描述行为。

重试控制

全新的 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, delaytimeout选项将会被无视。

异步组件也可以通过在选项中标明suspensible: false来退出默认的<Suspense>控制,始终自行控制其加载状态。

采纳策略

  • 语法转换是机械性的,可以通过代码被执行。挑战在于确定哪些简单功能应被视为异步组件。可以使用一些基本的方法:
    • 返回对于.vue文件的动态 import 调用的箭头函数
    • 返回一个拥有一个动态import调用作为自己component 属性的对象的箭头函数

请注意,这可能没办法完全覆盖目前的使用。

  • 在兼容版本中中,可以检查功能组件的返回值并警告旧版异步组件使用情况。这应该涵盖所有基于Promise的用例。
  • 唯一无法轻易检测到的情况是使用手动resolve/reject而不是返回Promise的2.x异步组件。在这种情况下,将需要手动升级,但是这种升级相对较少。

其他RFC

达瓦里希:Vue 3新特性RFC列表(翻译尚未完成)​zhuanlan.zhihu.com
938708dfd5c9c727b9e7e4f1fe62d830.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值