Skip to content

Commit ce14cd3

Browse files
committed
feat: 支持异步组件,组件内增加init初始化方法
1 parent e87a8e5 commit ce14cd3

File tree

4 files changed

+72
-1
lines changed

4 files changed

+72
-1
lines changed

docs/guide/component.md

+20
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,24 @@ class Foo extends VueComponent<Foo_Props> {
156156
)
157157
}
158158
}
159+
```
160+
161+
## 异步组件
162+
163+
异步组件需配合`vue`提供的`Suspense`组件使用,只需要组件内定义`init` 方法并且返回`promise`结果
164+
165+
```tsx
166+
class Foo extends VueComponent {
167+
async init() {
168+
await new Promise(r => setTimeout(r, 5000))
169+
}
170+
171+
render() {
172+
return (
173+
<div>
174+
{this.context.slots.item?.('aaaa')}
175+
</div>
176+
)
177+
}
178+
}
159179
```

example/module/basic/basic.module.tsx

+19-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Spin } from 'ant-design-vue'
2+
import { Suspense } from 'vue'
13
import { RouterView } from 'vue-router'
24
import { Hook, VueComponent } from 'vue3-oop'
35

@@ -7,6 +9,22 @@ export default class BasicModule extends VueComponent {
79
console.log(this.$parent)
810
}
911
render() {
10-
return <RouterView></RouterView>
12+
return (
13+
<RouterView>
14+
{({ Component }: { Component: any }) => {
15+
return (
16+
<div>
17+
<h2>111</h2>
18+
<Suspense
19+
v-slots={{
20+
default: () => [Component],
21+
fallback: () => <Spin>loading....</Spin>,
22+
}}
23+
></Suspense>
24+
</div>
25+
)
26+
}}
27+
</RouterView>
28+
)
1129
}
1230
}

example/module/basic/hello-world/hello-world.view.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import { Button, Card, Input } from 'ant-design-vue'
44
export default class HelloWorldView extends VueComponent {
55
@Mut() count = 1
66

7+
async init() {
8+
await new Promise((r) => setTimeout(r, 5000))
9+
}
10+
711
render() {
812
return (
913
<Card title={'加减功能'}>

src/extends/component.ts

+29
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ export class VueComponent<T extends {} = {}> {
125125

126126
/** 渲染函数 */
127127
render?(ctx: ComponentPublicInstance, cache: any[]): VNodeChild
128+
129+
/* 组件初始化逻辑,如果返回promise则为异步组件, 需配合 suspense 组件使用 */
130+
init?(): any
128131
}
129132
// 某些浏览器不支持 static get
130133
Object.defineProperty(VueComponent, '__vccOpts', {
@@ -148,6 +151,19 @@ Object.defineProperty(VueComponent, '__vccOpts', {
148151
const instance = VueComponent.resolveComponent(CompConstructor)
149152
// 支持模板
150153
if (CompConstructor.__vccOpts__value!.render) return instance
154+
// 支持异步组件
155+
if (typeof instance.init === 'function') {
156+
console.log('init func')
157+
const res = instance.init()
158+
if (
159+
res &&
160+
typeof res === 'object' &&
161+
typeof res.then === 'function'
162+
) {
163+
return res.then(() => instance.render.bind(instance))
164+
}
165+
}
166+
151167
return instance.render.bind(instance)
152168
},
153169
}
@@ -171,6 +187,19 @@ Object.defineProperty(VueComponent, '__vccOpts', {
171187
const instance = VueComponent.resolveComponent(CompConstructor)
172188
// 支持模板
173189
if (CompConstructor.__vccOpts__value!.render) return instance
190+
191+
// 支持异步组件
192+
if (typeof instance.init === 'function') {
193+
const res = instance.init()
194+
if (
195+
res &&
196+
typeof res === 'object' &&
197+
typeof res.then === 'function'
198+
) {
199+
return res.then(() => instance.render.bind(instance))
200+
}
201+
}
202+
174203
return instance.render.bind(instance)
175204
},
176205
}

0 commit comments

Comments
 (0)