@@ -13,3 +13,147 @@ class Foo extends VueComponent {
1313 }
1414}
1515```
16+
17+ ## 属性
18+
19+ 属性使用接口定义,在组件的 ` props ` 上面获取
20+
21+ ``` tsx
22+ import { VueComponent , ComponentProps } from ' vue3-oop'
23+
24+ interface Foo_Props {
25+ size: ' small' | ' large'
26+ }
27+
28+ class Foo extends VueComponent <Foo_Props > {
29+ static defaultProps: ComponentProps <Foo_Props > = [' size' ]
30+ render() {
31+ return <div >{ this .props .size } </div >
32+ }
33+ }
34+
35+ // 泛型组件
36+ interface Bar_Props <T = any > {
37+ data: T
38+ onChange: (item : T ) => void
39+ }
40+ class Bar <T > extends VueComponent <Bar_Props <T >> {
41+ static defaultProps: ComponentProps <Bar_Props > = [' data' , ' onChange' ]
42+ render() {
43+ return <div
44+ onClick = { () => this .props .onChange ?.(this .props .data )}
45+ >{ this .props .data } </div >
46+ }
47+ }
48+
49+ ```
50+
51+ ::: warning 注意!
52+ 定义属性之后一定要在类的静态属性 ` defaultProps ` 定义 vue 需要的属性定义
53+ :::
54+
55+ ## 上下文
56+
57+ 组件的 ` context ` 属性上面存储这个组件的 ` emit ` , ` slots ` , ` attrs ` , ` expose ` ,
58+ 就是setup函数的第二个参数
59+
60+ ``` tsx
61+ import { VueComponent } from ' ./component'
62+
63+ class Foo extends VueComponent {
64+ static inheritAttrs = false
65+
66+ render() {
67+ return <div { ... this .context .attrs } >foo</div >
68+ }
69+ }
70+ ```
71+
72+ ## 响应式变量
73+
74+ 响应式变量使用装饰器注解一下,主要有2个 ` Ref ` 和 ` Computed ` ,此时忘记 ` .value ` 的事情,
75+ 就是正常普通的变量定义,加上装饰器就是告诉框架当此变量变化的时候我要刷新视图
76+
77+ ``` tsx
78+ class Foo extends VueComponent {
79+ @Ref () count = 1
80+
81+ @Computed ()
82+ get doubleCount() {
83+ return this .count * 2
84+ }
85+
86+ render() {
87+ return (
88+ <div onClick = { () => this .count ++ } >
89+ { this .count }
90+ </div >
91+ )
92+ }
93+ }
94+ ```
95+
96+ ## 生命周期
97+
98+ 生命周期使用 ` Hook ` 装饰器
99+
100+ ``` tsx
101+ class Foo extends VueComponent {
102+ @Hook (' Mounted' )
103+ mounted() {
104+ console .log (' foo mounted' )
105+ }
106+
107+ render() {
108+ return <span >foo</span >
109+ }
110+ }
111+ ```
112+
113+ ## watch
114+
115+ watch在构造函数中使用, 构造函数其实就认为是 setup,你可以做任何在setup中使用的方法
116+
117+ ``` tsx
118+ import { watch } from ' vue'
119+
120+ class Foo extends VueComponent {
121+ constructor () {
122+ super ()
123+ watch (() => this .count , (n , o ) => console .log (' change' , n , o ))
124+ }
125+
126+ @Ref () count = 1
127+
128+ render() {
129+ return <span onClick = { () => this .count ++ } >{ this .count } </span >
130+ }
131+ }
132+ ```
133+
134+ ## 插槽
135+
136+ slots本质上其实是属性的一部分,为了模板的需要单独给拿出来,他其实就是类似于 ` react ` 中的 ` renderProps ` ,
137+ 所以我们可以在属性定义的时候定义一下,
138+
139+ ``` tsx
140+ import { VNodeChild } from ' vue'
141+ import { VueComponent } from ' vue3-oop'
142+
143+ interface Foo_Props {
144+ slots: {
145+ item(name : string ): VNodeChild
146+ }
147+ }
148+
149+ // 此时如果只有slots的话就可以不用定义 defaultProps
150+ class Foo extends VueComponent <Foo_Props > {
151+ render() {
152+ return (
153+ <div >
154+ { this .context .slots .item ?.(' aaaa' )}
155+ </div >
156+ )
157+ }
158+ }
159+ ```
0 commit comments