|
80 | 80 |
|
81 | 81 | // defineAsyncComponent 函数用于定义一个异步组件,接收一个异步组件加载器作为参数
|
82 | 82 | function defineAsyncComponent (options) {
|
83 |
| - // options 可以是配置项,也可以是加载器 |
84 | 83 | if (typeof options === 'function') {
|
85 |
| - // 如果 options 是加载器,则将其格式化为配置项形式 |
86 | 84 | options = {
|
87 | 85 | loader: options
|
88 | 86 | }
|
|
91 | 89 | const { loader } = options
|
92 | 90 |
|
93 | 91 | let InnerComp = null
|
94 |
| - // 返回一个包装组件 |
| 92 | + |
95 | 93 | return {
|
96 | 94 | name: 'AsyncComponentWrapper',
|
97 | 95 | setup () {
|
98 |
| - // 异步组件是否加载成功 |
99 | 96 | const loaded = ref(false)
|
100 |
| - // 代表是否超时,默认为 false,既没有超时 |
101 |
| - const timeout = ref(false) |
102 |
| - // 执行加载器函数,返回一个 Promise 实例 |
103 |
| - // 加载成功后,将加载成功的组件赋值给 InnerComp,并将 loaded 标记为 true,代表加载成功 |
104 |
| - loader().then(c => { |
105 |
| - InnerComp = c |
106 |
| - loaded.value = true |
107 |
| - }) |
| 97 | + // 定义 error,当错误发生时,用来存储错误对象 |
| 98 | + const error = shallowRef(null) |
| 99 | + |
| 100 | + loader() |
| 101 | + .then(c => { |
| 102 | + InnerComp = c |
| 103 | + loaded.value = true |
| 104 | + }) |
| 105 | + // 添加 catch 语句来捕获加载过程中的错误 |
| 106 | + .catch((err) => error.value = err) |
| 107 | + |
| 108 | + let timer = null |
| 109 | + if (options.timeout) { |
| 110 | + timer = setTimeout(() => { |
| 111 | + // 超时后创建一个错误对象,并复制给 error.value |
| 112 | + const err = new Error(`Async component timed out after ${ options.timeout }ms.`) |
| 113 | + error.value = err |
| 114 | + }, options.timeout) |
| 115 | + } |
| 116 | + |
| 117 | + const placeholder = { type: Text, children: '' } |
108 | 118 |
|
109 | 119 | return () => {
|
110 |
| - // 如果异步组件加载成功,则渲染该组件,否则渲染一个占位内容 |
111 |
| - return loaded.value ? { type: InnerComp } : { type: Text, children: '' } |
| 120 | + if (loaded.value) { |
| 121 | + return { type: InnerComp } |
| 122 | + } else if (error.value && options.errorComponent) { |
| 123 | + // 只有当错误存在且用户配置了 errorComponent 时才展示 Error 组件,同时将 error 作为 props 传递 |
| 124 | + return { type: options.errorComponent, props: { error: error.value } } |
| 125 | + } else { |
| 126 | + return placeholder |
| 127 | + } |
112 | 128 | }
|
113 | 129 | }
|
114 | 130 | }
|
|
0 commit comments