You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: active-rfcs/0000-class-api.md
+10-47Lines changed: 10 additions & 47 deletions
Original file line number
Diff line number
Diff line change
@@ -142,6 +142,16 @@ class MyComponent extends Vue {
142
142
}
143
143
```
144
144
145
+
#### Usage with Private Fields
146
+
147
+
Note that private fields are **NOT** reactive, because they are private to the class and thus cannot be inspected by framework code, which is required to create reactive state for them. Incidentally, they can be used to declare properties that should not be observed by Vue:
148
+
149
+
```js
150
+
classMyComponentextendsVue {
151
+
#renderer =new3DRenderer() // will not be observed by Vue
152
+
}
153
+
```
154
+
145
155
#### A Note on `[[Set]]` vs `[[Define]]`
146
156
147
157
The class field syntax uses `[[Define]]` semantics in both native and transpiled implementations (Babel already conforms to the latest spec and TS will have to follow suite). This means `count = 0` in the class body is executed with the semantics of `Object.defineProperty` and will always overwrite a property of the same name inherited from a parent class, regardless of whether it has a setter or not.
@@ -481,53 +491,6 @@ The decision to go with decorators for props in TypeScript is due to the followi
481
491
482
492
5. If users are using TypeScript, they already have decorators available to them via TypeScript's tool chain so unlike vanilla JavaScript there's no need for additional tooling.
483
493
484
-
## `this` Identity in `constructor`
485
-
486
-
In Vue 3 component classes, the `this` context in all lifecycle hooks and methods are in fact a Proxy to the actual underlying instance. This Proxy is responsible for returning proper values for the data, props and computed properties defined on the current component, and provides runtime warning checks. It is important for performance reasons as it avoids many expensive `Object.defineProperty` calls when instantiating components.
487
-
488
-
In practice, your code will work exactly the same - the only cases where you need to pay attention is if you are using `this` inside the native `constructor` - this is the only place where Vue cannot swap the identity of `this` so it will not be equal to the `this` exposed everywhere else:
489
-
490
-
```js
491
-
let instance
492
-
493
-
classMyComponentextendsVue {
494
-
constructor() {
495
-
super()
496
-
instance =this// actual instance
497
-
}
498
-
499
-
created() {
500
-
console.log(this=== instance) // false, `this` here is the Proxy
501
-
}
502
-
}
503
-
```
504
-
505
-
In practice, there shouldn't be cases where you must use the `constructor`, so the best practice is to simply avoid it and always use component lifecycle hooks.
506
-
507
-
## Usage with Private Fields
508
-
509
-
Due to `this` being Proxies, this API won't work directly with [Private Class Fields](https://github.com/tc39/proposal-private-methods) (stage 3 proposal), because private fields by design are not exposed on Proxies of the original instance. So the following will not work:
510
-
511
-
```js
512
-
classFooextendsVue {
513
-
#count =0
514
-
created() {
515
-
this.#count // Error because `this` is a Proxy
516
-
}
517
-
}
518
-
```
519
-
520
-
The runtime is able to detect this type of Errors and provide appropriate warnings. We can expose the raw, original instance as a special property on the proxy (naming tentative):
521
-
522
-
```js
523
-
classFooextendsVue {
524
-
#count =0
525
-
created() {
526
-
this.$self.#count // confirmed to work in Chrome 73
527
-
}
528
-
}
529
-
```
530
-
531
494
## Two Ways of Doing the Same Thing
532
495
533
496
This may cause beginners to face a choice early on: to go with the object syntax, or the class syntax?
0 commit comments