From 39c0be5b8c3365f9ba05d5fcf9dcafb2d6aa37cb Mon Sep 17 00:00:00 2001 From: Alex Chiu Date: Sun, 11 Oct 2020 09:01:13 +0100 Subject: [PATCH 1/7] Moved class components to a dedicated page --- README.md | 60 --------------------------------------------- class-components.md | 59 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 60 deletions(-) create mode 100644 class-components.md diff --git a/README.md b/README.md index 42d4e71..7261aa8 100644 --- a/README.md +++ b/README.md @@ -87,66 +87,6 @@ const Component = defineComponent({ }); ``` -### Class Components -[Vue Class Components](https://class-component.vuejs.org/) offers an alternative class-style syntax for Vue components which integrates well with TypeScript. - -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). - - -To get started with both libraries in your existing Vue project, run: -``` -npm install vue-class-component vue-property-decorator -``` - -You only need to import `vue-property-decorator` into your `.vue` file as it extends `vue-class-component`. - -You can now write TS in your components like this: - -```vue - - - -``` -See the [full guide for Vue Class Components](https://class-component.vuejs.org/guide/class-component.html#data). - -> _Class components should not confused with the now abandoned [Class API proposal](https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121)._ - ## Props `PropType` can be used to annotate props with a particular object shape. diff --git a/class-components.md b/class-components.md new file mode 100644 index 0000000..359a468 --- /dev/null +++ b/class-components.md @@ -0,0 +1,59 @@ +# Class Components +[Vue Class Components](https://class-component.vuejs.org/) offers an alternative class-style syntax for Vue components which integrates well with TypeScript. + +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). + + +To get started with both libraries in your existing Vue project, run: +``` +npm install vue-class-component vue-property-decorator +``` + +You only need to import `vue-property-decorator` into your `.vue` file as it extends `vue-class-component`. + +You can now write TS in your components like this: + +```vue + + + +``` +See the [full guide for Vue Class Components](https://class-component.vuejs.org/guide/class-component.html#data). + +> _Class components should not confused with the now abandoned [Class API proposal](https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121)._ From d31fa1fece6ec0946753d3e119b02d2bd3470589 Mon Sep 17 00:00:00 2001 From: Alex Chiu Date: Sun, 11 Oct 2020 11:21:42 +0100 Subject: [PATCH 2/7] Moved over section re: props and class components over from readme.md --- class-components.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/class-components.md b/class-components.md index 359a468..146774e 100644 --- a/class-components.md +++ b/class-components.md @@ -1,4 +1,7 @@ # Class Components + +## Overview + [Vue Class Components](https://class-component.vuejs.org/) offers an alternative class-style syntax for Vue components which integrates well with TypeScript. 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). @@ -57,3 +60,23 @@ export default class Hello extends Vue { See the [full guide for Vue Class Components](https://class-component.vuejs.org/guide/class-component.html#data). > _Class components should not confused with the now abandoned [Class API proposal](https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121)._ + +## Props +You can use the `Prop` decorator to annoate your prop types like so: + +```ts + +``` \ No newline at end of file From 7963ad93cad8230dee790e0c7845d552b01b6132 Mon Sep 17 00:00:00 2001 From: Alex Chiu Date: Sun, 11 Oct 2020 11:23:54 +0100 Subject: [PATCH 3/7] -Added link to class components md - Included section on Computed Properties --- README.md | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 7261aa8..8d57f1d 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ Cheatsheets for experienced Vue developers getting started with TypeScript. - [Vue 3 specifics](vue-3.md) +- [Class Components & Decorators](class-components.md) # Section 1: Setup @@ -116,26 +117,7 @@ export default Vue.extend({ ``` -With vue-class-components and vue-property-decorator, you can use the `Prop` decorator: - -```vue - -``` - -## Data Properties +## Data Properties (Options API) You can enforce types on Vue data properties by annotating the return data object: @@ -182,6 +164,30 @@ export default Vue.extend({ ``` 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. +## Computed Properties (Options API) + +Typing the return type for your computed properties is important especially when `this` is involved as TypeScript sometimes has trouble infering the type. + +```ts + +export default Vue.extend({ + data() { + return { + name: 'World', + } + }, + computed: { + greet(): string { //👈 Remember to annotate your computed properties like so. + return 'Hello ' + this.name + }, + } +}) + +``` + +> + + # Other Vue + TypeScript resources - Views on Vue podcast - https://devchat.tv/views-on-vue/vov-076-typescript-tell-all-with-jack-koppa/ - Focuses a lot on class components and vue-property-decorator - https://blog.logrocket.com/how-to-write-a-vue-js-app-completely-in-typescript/ From 3908106341c303aaa402c8479be7f649563ad926 Mon Sep 17 00:00:00 2001 From: Alex Chiu Date: Thu, 15 Oct 2020 21:28:39 +0100 Subject: [PATCH 4/7] Expanded class components props example --- class-components.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/class-components.md b/class-components.md index 146774e..4e403c3 100644 --- a/class-components.md +++ b/class-components.md @@ -76,7 +76,33 @@ interface PersonInfo { @Component export default class InfoCard extends Vue { - @Prop({ required: true }) readonly info: PersonInfo; + @Prop() readonly info!: PersonInfo; + @Prop({ default: false }) readonly admin?: boolean; } +``` +Is equivalent to: + +```ts +import Vue from "vue-property-decorator"; +import Vue, { PropType } from 'vue' + +interface PersonInfo { + firstName: string, + surname: string, + age: number +} +export default { + props: { + info: { + type: Object as PropType, + required: true + }, + admin: { + type: Boolean, + default: false + } + }, +} + ``` \ No newline at end of file From ce4175bac07e4567490e4e17514b3cf3471c4113 Mon Sep 17 00:00:00 2001 From: Alex Chiu Date: Fri, 16 Oct 2020 17:30:53 +0100 Subject: [PATCH 5/7] Included alternative example to annoate props with anon function --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index 8d57f1d..a4fc36c 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,33 @@ export default Vue.extend({ ``` +Alternatively, you can also annote your prop types with an anonymous function: + +```vue +import Vue from 'vue' + + +``` + ## Data Properties (Options API) You can enforce types on Vue data properties by annotating the return data object: From 6166ede2b1d57efcd959ae59e45801bd9ea6362f Mon Sep 17 00:00:00 2001 From: Alex Chiu Date: Mon, 19 Oct 2020 20:37:57 +0100 Subject: [PATCH 6/7] Typing ref's examples --- vue-3.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/vue-3.md b/vue-3.md index 62b93bb..5192996 100644 --- a/vue-3.md +++ b/vue-3.md @@ -30,3 +30,46 @@ declare const props: { export const welcome = computed(() => `Welcome, ${props.name}!`) ``` + +## Composition API + +### Refs + +Vue can infer the type of your `ref`'s but if you need to represent some more complex types you can do so with generics: + +```ts +import {ref} from "vue" + +interface PersonInfo { + firstName: string, + surname: string, + age: number +} + +const people = ref([]) + +``` + +Alternatively you can use casting with `as`. This should be used if the type is unknown. Consider this example where we create a composition wrapper function around `fetch` and we dont know the data structure that will be returned. + +```ts + +import { ref, Ref } from "vue"; + +type ApiRequest = () => Promise; + +// When using this function we can supply the type via generics +export function useAPI(url: RequestInfo, options?: RequestInit) { + + const response = ref() as Ref; // 👈 note we're typing our ref using `as` + + const request: ApiRequest = async () => { + const resp = await fetch(url, options); + const data = await resp.json(); + response.value = data; + }; + + return { response, request }; +} + +``` \ No newline at end of file From 81e087ea2c77bf41257b510284597e2ebbe08680 Mon Sep 17 00:00:00 2001 From: Alex Chiu Date: Mon, 19 Oct 2020 20:40:55 +0100 Subject: [PATCH 7/7] Added video by Modus Create, Inc to resources --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a4fc36c..0d7ea93 100644 --- a/README.md +++ b/README.md @@ -218,3 +218,4 @@ export default Vue.extend({ # Other Vue + TypeScript resources - Views on Vue podcast - https://devchat.tv/views-on-vue/vov-076-typescript-tell-all-with-jack-koppa/ - Focuses a lot on class components and vue-property-decorator - https://blog.logrocket.com/how-to-write-a-vue-js-app-completely-in-typescript/ +- Vue 3 Hooks and Type Safety with TypeScript - https://www.youtube.com/watch?v=aJdi-uEKYAc