Skip to content

Commit 07ef3a6

Browse files
committed
feat: 增加类型帮助函数
1 parent 6a66603 commit 07ef3a6

File tree

8 files changed

+101
-16
lines changed

8 files changed

+101
-16
lines changed

docs/.vitepress/config.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,35 @@ const config: UserConfig = {
88
nav: [
99
{ text: '指南', link: '/guide/', activeMatch: '^/guide/' },
1010
{
11-
text: 'API参考',
12-
link: '/api/',
13-
activeMatch: '^/api/',
11+
text: 'DEMO',
12+
link: 'https://stackblitz.com/edit/vite-y7m4fy?file=main.tsx',
1413
},
1514
{
1615
text: 'Github',
1716
link: 'https://github.com/agileago/vue3-oop',
1817
},
1918
],
19+
sidebar: {
20+
'/guide/': [
21+
{
22+
text: '介绍',
23+
children: [
24+
{ text: '使用指南', link: '/guide/' },
25+
{ text: '组件', link: '/guide/component' },
26+
{ text: '服务', link: '/guide/service' },
27+
{ text: '装饰器', link: '/guide/decorators' },
28+
],
29+
},
30+
{
31+
text: '依赖注入',
32+
children: [{ text: '服务注入', link: '/guide/di' }],
33+
},
34+
{
35+
text: '类型',
36+
children: [{ text: '类型帮助', link: '/guide/type' }],
37+
},
38+
],
39+
},
2040
},
2141
}
2242

docs/guide/component.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#

docs/guide/index.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# 如何使用
2+
3+
## 前提条件
4+
5+
1. 因为要用到ts的获取元数据的能力,所以需要安装`reflect-metada`的支持
6+
7+
```shell
8+
yarn add @abraham/reflection
9+
```
10+
并且把这段代码放到入口引入,只需引入一次
11+
12+
```typescript
13+
import '@abraham/reflection'
14+
```
15+
16+
2. 安装依赖注入库 `injection-js`, 以及本库
17+
18+
```shell
19+
yarn add injection-js vue3-oop
20+
```
21+
22+
3. 设置 `tsconfig.json`
23+
24+
主要是涉及到装饰器以及类的设置
25+
26+
```json
27+
{
28+
"compilerOptions": {
29+
"experimentalDecorators": true,
30+
"emitDecoratorMetadata": true,
31+
"useDefineForClassFields": false,
32+
}
33+
}
34+
```
35+
36+
4. 如果使用 `vite` 的话,由于vite使用`esbuild`编译`ts`,不支持 `metadata` , 需要把 `@vitejs/plugin-vue-jsx` 这个插件换成`vite-plugin-ts`这个插件
37+
38+
```shell
39+
yarn add vite-plugin-ts
40+
```
41+
42+
vite 插件配置
43+
```typescript
44+
import vueJsx from 'vite-plugin-ts'
45+
export default {
46+
plugins: [vueJsx()]
47+
}
48+
```
49+

docs/index.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,4 @@ features:
1111
details: 基于动态解析的 injection-js 依赖注入,让使用服务丝般自然
1212
- title: vue3无ref编程
1313
details: 无需关注ref及其value,正常声明变量,编程体验更自然
14-
---
15-
16-
17-
<iframe src="https://stackblitz.com/edit/vite-y7m4fy?embed=1&file=main.tsx" height="600" width="100%" frameborder="0"></iframe>
14+
---

example/main.tsx

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import '@abraham/reflection'
2+
import type { ClassType } from '@/index'
23
import { Autobind, Component, ComponentProps, Computed, Hook, Link, Ref, VueComponent, VueService } from '@/index'
34
import { forwardRef, Inject, Injectable, SkipSelf } from 'injection-js'
4-
import { createApp, watch } from 'vue'
5+
import { createApp, VNodeChild, watch } from 'vue'
56

67
// 服务,即可复用的逻辑 类似 useXXX
78
@Injectable()
@@ -22,6 +23,10 @@ class CountService extends VueService {
2223
// 组件属性声明
2324
interface HomeChild_Props {
2425
size: 'small' | 'large'
26+
// 组件个性化定义属性
27+
slots: {
28+
item(name: string): VNodeChild
29+
}
2530
}
2631

2732
// 带属性组件
@@ -34,7 +39,7 @@ class HomeChild extends VueComponent<HomeChild_Props> {
3439
constructor(
3540
private countService: CountService,
3641
@SkipSelf() private parentCountService: CountService,
37-
@Inject(forwardRef(() => Home)) private parent: InstanceType<typeof Home>,
42+
@Inject(forwardRef(() => Home)) private parent: ClassType<Home>,
3843
) {
3944
super()
4045
}
@@ -50,12 +55,16 @@ class HomeChild extends VueComponent<HomeChild_Props> {
5055
<button onClick={this.countService.add}>+</button>
5156
{this.countService.count}
5257
<button onClick={this.countService.remove}>-</button>
58+
<div>
59+
<h3>这里是组件定制化内容</h3>
60+
{this.context.slots.item?.('我是定制化内容')}
61+
</div>
5362
</div>
5463
)
5564
}
5665
}
57-
5866
// 组件
67+
@Autobind() // 绑定this 也可以放到这里
5968
@Component({ providers: [CountService] }) // 声明自己的服务
6069
class Home extends VueComponent {
6170
// 构造函数注入服务,无需new
@@ -83,14 +92,12 @@ class Home extends VueComponent {
8392
}
8493

8594
// 子组件引用 链接🔗
86-
@Link() child?: HomeChild
95+
@Link() child?: ClassType<HomeChild>
8796

88-
@Autobind()
8997
add() {
9098
this.count++
9199
}
92100

93-
@Autobind()
94101
remove() {
95102
this.count--
96103
}
@@ -108,7 +115,15 @@ class Home extends VueComponent {
108115
{this.count}
109116
<button onClick={this.remove}>-</button>
110117

111-
<HomeChild ref="child" size={'small'}></HomeChild>
118+
<HomeChild
119+
ref="child"
120+
size={'small'}
121+
v-slots={{
122+
item(name: string) {
123+
return <span>{name}</span>
124+
},
125+
}}
126+
></HomeChild>
112127
</div>
113128
)
114129
}

src/di/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export function Component(options?: ComponentOptions): ClassDecorator {
4141
export function resolveComponent(target: { new (...args: []): any }) {
4242
// 如果没有使用 injection-js 则不创建注入器
4343
if (!Reflect.getMetadata('annotations', target)) return new target()
44-
const parent = inject(InjectorKey)
44+
const parent = inject(InjectorKey, undefined)
4545
const options: ComponentOptions | undefined = Reflect.getOwnMetadata(MetadataKey, target)
4646
// 自动解析依赖,根据组件
4747
let deps: Provider[] = options?.autoResolveDeps ? resolveDependencies(target) : options?.providers || []

src/extends/component.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,6 @@ export type ComponentSlots<T extends { props: any }> = T extends { props: infer
103103
? U['v-slots']
104104
: Record<string, unknown>
105105
: never
106+
107+
/** 为了阻止ts把不相关的类也解析到metadata数据中,用这个工具类型包装一下类 */
108+
export type ClassType<T extends Record<string, any>> = T

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ export { Hook } from './decorators/hook'
77
export * from './helper'
88
export { Component, InjectorKey } from './di'
99
export type { ComponentOptions } from './di'
10-
export type { ComponentProps, ComponentSlots } from './extends/component'
10+
export type { ComponentProps, ComponentSlots, ClassType } from './extends/component'

0 commit comments

Comments
 (0)