A Simple Vue 2 Component with TypeScript

Prerequisite

Damiano Fusco
vuetypescript.com
4 min readFeb 27, 2020

--

This articles assumes you are already familiar on how to setup a Vue project with TypeScript using the vue-cli as described here: https://medium.com/@DamianoMe/vue-with-typescript-setup-using-vue-cli-scaling-vue-17a66e063f34

Note: this article is a free sample from my book Large Scale Apps with Vue and TypeScript https://leanpub.com/large-scale-apps-with-vue-and-typescript
Also please keep in mind that CodePen samples have been included only because makes it easier to format gists a bit better within medium for sample code, but they are not functional in CodePen.

The ItemsList Component

Let’s pretend we have been giving requirements for our app to have a component that simply displays a list of “items”. We are going to keep this quite simple initially and in future articles expand on it to demonstrate how we can better structure our application in order to support:

  • Quick prototyping and development using mocked data
  • Component Organization
  • Unit Testing
  • State Management with Vuex

ItemsList Component Requirements

Your initial version of the ItemsList component, will have to implement the following requirements (later, in more advanced chapters, we will expand on these as we get into more advanced topics):

  • The component will display a list of items
  • An item will have 3 properties:
  1. id
  2. name
  3. selected
  • The item name will be displayed to the user
  • The user should be able to select/deselect one or more item
  • An icon will be shown next to the name to indicate if the item is selected

ItemsList Component Code

Within the src/components directory, create a sub-directory called items. Within this folder add a new file called ItemsList.component.vue¹

Your directory structure will now look like this:

Within the ItemsList.component.vue file, paste the following code:

A few things to notice here. First, we specify the lang attribute on the <script> element with the value ts so we can use TypeScript. We also make use of class-style syntax. For our html template, we added a <h3> element with hard-coded tests just saying “My Items”. Then a <ul> with a v-for binding that will render all our items within <li> elements.

Within the <script> section, we import the @Component and @Prop decorators. Also a reference to Vue so we can extend it in our class declaration.

We then declare the items property as an array of any² for now.

Home View

Within the src/views directory, open the existing Home.vue file. This is the existing code that was stubbed by the vue-cli when we first created the project:

Remove the highlighted parts in red: the reference to the HelloWorld component within the <template>; the <img> element; clear the code within the <script> section. Also add the attribute lang=”ts” to the <script> section as we will be using TypeScript:

Now, similarly to how we did in our custom ItemsList.component.vue, lets import the @Component and @Prop decorators and start implementing our Home view (new and modified code is highlighted in yellow).

Then import a reference to the ItemsList.component.vue and register it through our @Component decorator.

For now, also quickly mock some data for our list of items that we’ll feed to our ItemsComponent. For this we add a private property to the Home class called items and initialize it with some hard-coded data³.

Finally, we add an <ItemsComponent> element within the <template> markup. We can insert it within the <div class=”home”> element for now. Add an attribute called :items to our <ItemsComponent>. This is how you do one-way binding in Vue. The Home items property with the hard-coded data is fed into the component items property this way. The complete code within the Home.vue file should not look like this:

Now, the web browser will refresh and display our preliminary items list being rendered more or less like this:

[1] We follow a file naming convention where Vue components are pascal-case and follow this format [ComponentName].component.vue (Reference: Naming Conventions section at the end of my book)

[2] With ‘any’, TypeScript does not enforce type-checking on a property or variable. However, this is considered a bad practice as we lose the main benefit of TypeScript. There might be exceptions to this rule when using older 3rd party packages/libraries/plugins that do not offer type definitions. However, even in those cases it would be strongly recommended to provide interfaces and types so that you can still avoid using ‘any’.

[3] Note: using hard-coded data is a bad practice and here we are only doing it to first illustrate how things flow, and later in the next chapters will remove in favor of best practices and patterns (see Chapter 5)

--

--

Damiano Fusco
vuetypescript.com

Build "Large Scale Apps with Vue 3 and TypeScript" http://leanpub.com/vue-typescript/c/X3hLzl6Ygtr2 #Developer, #VueJS, #JavaScript, #TypeScript