|
3 | 3 | Cheatsheets for experienced Vue developers getting started with TypeScript. |
4 | 4 |
|
5 | 5 | - [Vue 3 specifics](vue-3.md) |
| 6 | +- [Class Components & Decorators](class-components.md) |
6 | 7 |
|
7 | 8 | # Section 1: Setup |
8 | 9 |
|
@@ -87,66 +88,6 @@ const Component = defineComponent({ |
87 | 88 | }); |
88 | 89 | ``` |
89 | 90 |
|
90 | | -### Class Components |
91 | | -[Vue Class Components](https://class-component.vuejs.org/) offers an alternative class-style syntax for Vue components which integrates well with TypeScript. |
92 | | - |
93 | | -To have consistent support for decorators in your Vue components, it's also recommended to install [vue-property-decorator](https://github.com/kaorun343/vue-property-decorator). |
94 | | - |
95 | | - |
96 | | -To get started with both libraries in your existing Vue project, run: |
97 | | -``` |
98 | | -npm install vue-class-component vue-property-decorator |
99 | | -``` |
100 | | - |
101 | | -You only need to import `vue-property-decorator` into your `.vue` file as it extends `vue-class-component`. |
102 | | - |
103 | | -You can now write TS in your components like this: |
104 | | - |
105 | | -```vue |
106 | | -<template> |
107 | | - <div> |
108 | | - {{ count }} |
109 | | - <button v-on:click="increment">+</button> |
110 | | - <button v-on:click="decrement">-</button> |
111 | | - {{ computedValue }} |
112 | | - </div> |
113 | | -</template> |
114 | | -
|
115 | | -<script lang="ts"> |
116 | | -import { Vue, Component } from "vue-property-decorator"; |
117 | | -
|
118 | | -@Component |
119 | | -export default class Hello extends Vue { |
120 | | -
|
121 | | - count: number = 0 |
122 | | - vue: string = "vue" |
123 | | - ts: string = "ts" |
124 | | -
|
125 | | - // Lifecycle methods can be accessed like this |
126 | | - mounted() { |
127 | | - console.log('component mounted') |
128 | | - } |
129 | | -
|
130 | | - // Method are component methods |
131 | | - increment(): void { |
132 | | - this.count++ |
133 | | - } |
134 | | -
|
135 | | - decrement(): void { |
136 | | - this.count-- |
137 | | - } |
138 | | -
|
139 | | - // Computed values are getters |
140 | | - get computedValue(): string { |
141 | | - return `${vue} and ${ts} rocks!` |
142 | | - } |
143 | | -} |
144 | | -</script> |
145 | | -``` |
146 | | -See the [full guide for Vue Class Components](https://class-component.vuejs.org/guide/class-component.html#data). |
147 | | - |
148 | | -> _Class components should not confused with the now abandoned [Class API proposal](https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121)._ |
149 | | -
|
150 | 91 | ## Props |
151 | 92 |
|
152 | 93 | `PropType` can be used to annotate props with a particular object shape. |
@@ -176,26 +117,34 @@ export default Vue.extend({ |
176 | 117 | </script> |
177 | 118 | ``` |
178 | 119 |
|
179 | | -With vue-class-components and vue-property-decorator, you can use the `Prop` decorator: |
| 120 | +Alternatively, you can also annote your prop types with an anonymous function: |
180 | 121 |
|
181 | 122 | ```vue |
| 123 | +import Vue from 'vue' |
| 124 | +
|
182 | 125 | <script lang="ts"> |
183 | | -import { Vue, Component, Prop } from "vue-property-decorator"; |
| 126 | +import Vue from "vue"; |
184 | 127 |
|
185 | 128 | interface PersonInfo { |
186 | 129 | firstName: string, |
187 | 130 | surname: string, |
188 | 131 | age: number |
189 | 132 | } |
190 | 133 |
|
191 | | -@Component |
192 | | -export default class InfoCard extends Vue { |
193 | | - @Prop({ required: true }) readonly info: PersonInfo; |
194 | | -} |
| 134 | +export default Vue.extend({ |
| 135 | + |
| 136 | + name: "InfoCard", |
| 137 | + props: { |
| 138 | + info: { |
| 139 | + type: Object as () => PersonInfo, |
| 140 | + required: true |
| 141 | + } |
| 142 | + } |
| 143 | +}); |
195 | 144 | </script> |
196 | 145 | ``` |
197 | 146 |
|
198 | | -## Data Properties |
| 147 | +## Data Properties (Options API) |
199 | 148 |
|
200 | 149 | You can enforce types on Vue data properties by annotating the return data object: |
201 | 150 |
|
@@ -242,6 +191,31 @@ export default Vue.extend({ |
242 | 191 | ``` |
243 | 192 | Note that [type assertion](https://www.typescriptlang.org/docs/handbook/basic-types.html#type-assertions) like this does not provide any type safety. If for example, the `contents` property was missing in `newPost`, TypeScript would not catch this error. |
244 | 193 |
|
| 194 | +## Computed Properties (Options API) |
| 195 | + |
| 196 | +Typing the return type for your computed properties is important especially when `this` is involved as TypeScript sometimes has trouble infering the type. |
| 197 | + |
| 198 | +```ts |
| 199 | + |
| 200 | +export default Vue.extend({ |
| 201 | + data() { |
| 202 | + return { |
| 203 | + name: 'World', |
| 204 | + } |
| 205 | + }, |
| 206 | + computed: { |
| 207 | + greet(): string { //👈 Remember to annotate your computed properties like so. |
| 208 | + return 'Hello ' + this.name |
| 209 | + }, |
| 210 | + } |
| 211 | +}) |
| 212 | + |
| 213 | +``` |
| 214 | + |
| 215 | +> |
| 216 | +
|
| 217 | + |
245 | 218 | # Other Vue + TypeScript resources |
246 | 219 | - Views on Vue podcast - https://devchat.tv/views-on-vue/vov-076-typescript-tell-all-with-jack-koppa/ |
247 | 220 | - Focuses a lot on class components and vue-property-decorator - https://blog.logrocket.com/how-to-write-a-vue-js-app-completely-in-typescript/ |
| 221 | +- Vue 3 Hooks and Type Safety with TypeScript - https://www.youtube.com/watch?v=aJdi-uEKYAc |
0 commit comments