Typescript Component decorator (like Angular)

Typescript @Component decorator to Vue.js
Difficulty

Let’s first see what might be the reasons for wanting to include a Typescript Component decorator.
In case you want to create a FE application developed in Typescript, often one of the main reasons is the fact that you come from applications in Angular, one of the most used frameworks when it comes to this type of technology.
In this case you will surely want to use the good old decorator for inserting certain attributes to our component. To do this, we have to perform an installation of the module designed to do this:

npm i -S nuxt-property-decorator

After installation, the components can be developed following the more comfortable class mode with also the decorator that in Angular is already used for any component, @Component.

<script lang="ts">
  import { Component, Vue } from 'nuxt-property-decorator';
  
  @Component({
    components: {},
  })
  export default class MyComponent extends Vue {}
</script>


Note that the lang="ts" attribute has been inserted in the script tag for correct compilation in the expected language.

Furthermore, for the correct inclusion of other components, since these are typescripts, we have to define that we must include these components within others. We can do that adding its type through a file in root: shims-vue.d.ts.

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

Typescript Component decorator usage

Inside it we can then go on to define its properties and the classic methods for the lifecycle. This in a more object-oriented form.

<script lang="ts">
  import { Component, Vue } from 'nuxt-property-decorator';

  @Component
  export default class MyComponent extends Vue {
    loadedMyComponent: boolean = false;

    mounted() {
      this.loadedMyComponent = true;
      console.log('Mounted my component');
    }
  }
</script>

Once we have defined this type of approach, we don’t have to use this system for everything. We can either continue with this form but also define components via Vue methods like defineComponent({…});
Let’s take an example of a component that adds the writing loading inside others. For instance we are in the case of loading data from outside. We can either create it via defineComponent() or with the associated decorator (although in this case, quite useless).
However, it may be convenient to maintain a linearity in the creation of all the components of the page.

<template>
  <div class="loading">Loading</div>
</template>

<script lang="ts">
  import { defineComponent } from 'vue';

  export default defineComponent({
    name: 'LoadingComponent',
    methods: {},
  });
</script>
<template>
  <div class="loading">Loading</div>
</template>

<script>
  import { Component, Vue } from 'nuxt-property-decorator';

  @Component
  export default class LoadingComponent extends Vue {}
</script>

To insert a component in our class version, we can use the decorator to establish the insertion. Then we will safely use our component included within the parent component.

<template>
  <div>
    <p>This component is:</p>
    <LoadingComponent></LoadingComponent>
  </div>
</template>

<script lang="ts">
  import { Component, Vue } from 'nuxt-property-decorator';
  import LoadingComponent from "./LoadingComponent.vue";

  @Component({
    components: {
      LoadingComponent,
    },
  })
  export default class MyComponent extends Vue {
    loading: boolean = false;

    mounted() {
      this.getResources();
    }

    async getResources() {
      this.loading = true;
      // const res = await $api.getResources();
      // this.resources = res.map(Resource.adapt) as Resource[];
      this.loading = false;
    }
  }
</script>


That’s all to create a component with Typescript decorator.
Try it at home!

0
Be the first one to like this.
Please wait...

Leave a Reply

Thanks for choosing to leave a comment.
Please keep in mind that all comments are moderated according to our comment policy, and your email address will NOT be published.
Please do NOT use keywords in the name field. Let's have a personal and meaningful conversation.