@@ -30,6 +30,7 @@ type VueComponentProps<T extends {}> = Omit<T, 'slots'> &
30
30
AllowedComponentProps &
31
31
Record < string , unknown >
32
32
33
+ // @ts -ignore
33
34
export abstract class VueComponent < T extends { } = { } > {
34
35
/** 热更新使用 */
35
36
static __hmrId ?: string
@@ -49,25 +50,54 @@ export abstract class VueComponent<T extends {} = {}> {
49
50
static globalStore ?: boolean
50
51
/** 是否把自己当做服务provide出去,以便子组件可注入 */
51
52
static ProviderKey ?: string | symbol | number | InjectionKey < any >
52
- /** 主要给jsx提示用 */
53
- get $props ( ) {
54
- return this . props
55
- }
56
53
/** 组件属性 */
57
54
public props = useProps < VueComponentProps < T > > ( )
58
55
/** 组件上下文 */
59
56
public context = useCtx ( ) as WithSlotTypes < T >
60
57
/** 组件内部实例,如果使用组件实例请 this.$.proxy */
61
58
public $ = getCurrentInstance ( ) !
59
+ /** 主要给jsx提示用 */
60
+ get $props ( ) {
61
+ return this . props
62
+ }
63
+ get $el ( ) {
64
+ return this . $ . proxy ?. $el
65
+ }
66
+ get $refs ( ) {
67
+ return this . $ . proxy ?. $refs
68
+ }
69
+ get $parent ( ) {
70
+ return this . $ . proxy ?. $parent
71
+ }
72
+ get $root ( ) {
73
+ return this . $ . proxy ?. $root
74
+ }
75
+ get $emit ( ) {
76
+ return this . $ . proxy ?. $emit
77
+ }
78
+ get $forceUpdate ( ) {
79
+ return this . $ . proxy ?. $forceUpdate
80
+ }
81
+ get $nextTick ( ) {
82
+ return this . $ . proxy ?. $nextTick
83
+ }
84
+ get $watch ( ) {
85
+ return this . $ . proxy ?. $watch
86
+ }
62
87
63
88
constructor ( ) {
64
- this . context . expose ( this )
89
+ markRaw ( this )
90
+ // 处理ref
91
+ const current = this . $
92
+ // 由于vue会包装一层,会自动代理ref,导致类型错误, 还导致不能修改变量
93
+ current . exposed = this
94
+ current . exposeProxy = this
95
+
96
+ // 处理依赖注入
65
97
const ThisConstructor = this . constructor as VueComponentStaticContructor
66
98
if ( ThisConstructor . ProviderKey ) provide ( ThisConstructor . ProviderKey , this )
67
99
if ( ThisConstructor . globalStore ) {
68
100
// 如果作为全局的服务,则注入到根上面
69
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
70
- const current = getCurrentInstance ( ) !
71
101
const app = current . appContext . app
72
102
app . provide ( GlobalStoreKey , this )
73
103
app . getStore = ( ) => this
@@ -82,13 +112,14 @@ export abstract class VueComponent<T extends {} = {}> {
82
112
return current ?. provides [ token ]
83
113
}
84
114
}
115
+
85
116
VueComponent . handler . forEach ( ( handler ) => handler . handler ( this ) )
86
117
}
87
118
88
119
/** 渲染函数 */
89
120
render ?( ctx : ComponentPublicInstance , cache : any [ ] ) : VNodeChild
90
121
}
91
- // 为了支持es5浏览器
122
+ // 某些浏览器不支持 static get
92
123
Object . defineProperty ( VueComponent , '__vccOpts' , {
93
124
enumerable : true ,
94
125
configurable : true ,
@@ -123,3 +154,13 @@ Object.defineProperty(VueComponent, '__vccOpts', {
123
154
} )
124
155
} ,
125
156
} )
157
+
158
+ // 处理forwardref
159
+ export function useForwardRef ( ) {
160
+ const instance = getCurrentInstance ( ) !
161
+ function forwardRef ( ref : any ) {
162
+ instance . exposed = ref
163
+ instance . exposeProxy = ref
164
+ }
165
+ return forwardRef
166
+ }
0 commit comments