|
11 | 11 | <div id="app"></div>
|
12 | 12 | <script src=" https://unpkg.com/@vue/[email protected]/dist/reactivity.global.js" ></script>
|
13 | 13 | <script>
|
14 |
| - |
15 |
| - const { effect, reactive, shallowReactive, shallowReadonly } = VueReactivity |
| 14 | + const { effect, reactive, shallowReactive, shallowReadonly, shallowRef } = VueReactivity |
16 | 15 | function shouldSetAsProps (el, key, value) {
|
17 | 16 | if (key === 'form' && el.tagName === 'INPUT') return false
|
18 | 17 | return key in el
|
|
94 | 93 | name: 'AsyncComponentWrapper',
|
95 | 94 | setup () {
|
96 | 95 | const loaded = ref(false)
|
| 96 | + // 代表是否超时,默认为 false,既没有超时 |
| 97 | + // const timeout = ref(false) |
97 | 98 | // 定义 error,当错误发生时,用来存储错误对象
|
98 |
| - const error = shallowRef(null) |
99 |
| - |
100 |
| - loader() |
101 |
| - .then(c => { |
102 |
| - InnerComp = c |
103 |
| - loaded.value = true |
104 |
| - }) |
| 99 | + const error = shallowRef(null, loaded) |
| 100 | + // 执行加载器函数,返回一个 Promise 实例 |
| 101 | + // 加载成功后,将加载成功的组件赋值给 InnerComp,并将 loaded 标记为 true,代表加载成功 |
| 102 | + loader().then(c => { |
| 103 | + InnerComp = c |
| 104 | + loaded.value = true |
105 | 105 | // 添加 catch 语句来捕获加载过程中的错误
|
106 |
| - .catch((err) => error.value = err) |
107 |
| - |
| 106 | + }).catch((err) => error.value = err) |
108 | 107 | let timer = null
|
109 | 108 | if (options.timeout) {
|
| 109 | + // 如果指定了超时时长,则开启一个定时器计时 |
110 | 110 | timer = setTimeout(() => {
|
111 | 111 | // 超时后创建一个错误对象,并复制给 error.value
|
112 |
| - const err = new Error(`Async component timed out after ${ options.timeout }ms.`) |
| 112 | + const err = new Error(`Async component timed out after ${ options.timeout } seconds.timeout="${ options.timeout }ms.`) |
113 | 113 | error.value = err
|
| 114 | + // 超时后将 timeout 设置为 true |
| 115 | + // timeout.value = true |
114 | 116 | }, options.timeout)
|
115 | 117 | }
|
| 118 | + // 包装组件被卸载时清除定时器 |
| 119 | + onUmounted(() => clearTimeout(timer)) |
116 | 120 |
|
| 121 | + // 占位内容 |
117 | 122 | const placeholder = { type: Text, children: '' }
|
118 | 123 |
|
119 | 124 | return () => {
|
120 | 125 | if (loaded.value) {
|
| 126 | + // 如果组件异步加载成功,则渲染被加载的组件 |
121 | 127 | return { type: InnerComp }
|
| 128 | + // } else if (timeout.value) { |
122 | 129 | } else if (error.value && options.errorComponent) {
|
| 130 | + // 如果加载超时,并且用户指定了 Error 组件,则渲染该组件 |
| 131 | + // return options.errorComponent ? { type: options.errorComponent } : placeholder |
123 | 132 | // 只有当错误存在且用户配置了 errorComponent 时才展示 Error 组件,同时将 error 作为 props 传递
|
124 | 133 | return { type: options.errorComponent, props: { error: error.value } }
|
125 |
| - } else { |
126 |
| - return placeholder |
127 | 134 | }
|
| 135 | + return placeholder |
128 | 136 | }
|
129 | 137 | }
|
130 | 138 | }
|
|
0 commit comments