Lesson 10-Vue3 Integration with TypeScript

Creating a TypeScript Project

To start a Vue 3 project with TypeScript, you can use Vue CLI. Follow these steps:

# Install Vue CLI
npm install -g @vue/cli

# Create a project
vue create my-ts-project
? Check the features needed for your project (Press <space> to select, <a> to toggle all, <i> to invert selection):
 TypeScript
  Babel
  PWA
  Router
  Vuex
  CSS Pre-processors
  Linter / Formatter
  Unit Testing
  E2E Testing
? Pick a TypeScript compiler that should be used in this project (Use arrow keys)
 Babel + TypeScript (JavaScript and TypeScript compilation with Babel, powered by @babel/preset-typescript)
  TypeScript + ts-loader (Full TypeScript support with ts-loader)
  TypeScript + babel-ts-loader (Full TypeScript support with babel-ts-loader)

Select the TypeScript option and complete the configuration as prompted.

Writing TypeScript Components

In Vue 3, you can use TypeScript in .vue files. Here’s an example of a simple component:

// src/components/HelloWorld.vue
<template>
  <div>{{ message }}</div>
</template>

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

export default defineComponent({
  name: 'HelloWorld',
  props: {
    msg: String,
  },
  setup(props) {
    const message = `Hello, ${props.msg}!`;
    return { message };
  },
});
</script>

This defines a HelloWorld component that accepts a msg prop and displays a message in the template.

Writing a TypeScript Store

Pinia, the recommended state management library for Vue 3, integrates seamlessly with TypeScript.

// src/stores/user.ts
import { defineStore } from 'pinia';

export const useUserStore = defineStore('user', {
  state: () => ({
    name: '' as string,
    age: 0,
  }),
  getters: {
    fullName: (state) => `${state.name} Doe`,
  },
  actions: {
    updateName(name: string) {
      this.name = name;
    },
  },
});

This example defines a user Store with state, a getter, and an action, all typed for safety.

Handling Type Issues

When using TypeScript, you may encounter type-related issues, especially with ref or reactive. Explicitly define types to resolve them:

// src/components/Counter.vue
import { ref } from 'vue';

export default {
  setup() {
    const count = ref<number>(0);
    const increment = () => {
      count.value++;
    };

    return {
      count,
      increment,
    };
  },
};

Here, count is explicitly typed as a number to ensure type safety.

Writing TypeScript for Vue Router

Vue Router supports TypeScript, enhancing type safety with type declarations:

// src/router/index.ts
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue';

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home,
  },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;

This example sets up a type-safe router with a single route.

Writing TypeScript for Vue CLI Plugins

When developing Vue CLI plugins, TypeScript provides better type checking and editor support.

// src/plugin.ts
import { PluginObject } from '@vue/cli-service';

const plugin: PluginObject<any> = {
  install: (_options, context) => {
    context.service.addCommand({
      name: 'my-command',
      description: 'A custom command',
      action: async () => {
        console.log('Running my-command');
      },
    });
  },
};

export default plugin;

This plugin defines a custom CLI command with TypeScript.

Writing TypeScript for Vue 3 Plugins

Vue 3 plugins can be written in TypeScript to ensure type correctness.

// src/plugins/my-plugin.ts
import { App } from 'vue';

const install = (app: App) => {
  app.config.globalProperties.$myMethod = () => {
    console.log('Calling myMethod');
  };
};

export default { install };

This plugin adds a global method to the Vue app with type safety.

Writing TypeScript for Unit Tests

TypeScript enhances unit tests by ensuring type correctness in test code.

// tests/unit/components/HelloWorld.spec.ts
import { shallowMount } from '@vue/test-utils';
import HelloWorld from '@/components/HelloWorld.vue';

describe('HelloWorld.vue', () => {
  it('displays the correct message', () => {
    const wrapper = shallowMount(HelloWorld, {
      props: {
        msg: 'World',
      },
    });
    expect(wrapper.text()).toContain('Hello, World!');
  });
});

This test verifies the HelloWorld component’s output with type-safe code.

Writing TypeScript for Custom Directives

Vue 3 allows custom directives to be written in TypeScript for type safety.

// src/directives/focus.ts
import { DirectiveBinding } from 'vue';

const focus: DirectiveBinding<() => void> = {
  mounted(el) {
    el.focus();
  },
};

export default focus;

This custom directive automatically focuses an element on mount, with typed bindings.

Writing TypeScript for Vue 3 Directives

Vue 3’s built-in directives can also leverage TypeScript for enhanced type safety.

Code Analysis

  • Project Setup: Vue CLI simplifies creating TypeScript-enabled Vue 3 projects with configurable compiler options.
  • Components: TypeScript in .vue files ensures type-safe props and setup logic using defineComponent.
  • State Management: Pinia integrates seamlessly with TypeScript for typed stores, getters, and actions.
  • Routing: Vue Router supports TypeScript for type-safe route definitions.
  • Plugins and Directives: TypeScript enhances Vue CLI plugins, Vue 3 plugins, and custom directives with strict typing.
  • Testing: TypeScript ensures type safety in unit tests, improving reliability and maintainability.
Share your love