Code Monkey home page Code Monkey logo

vue's Introduction

Vue+TypeScript Cheatsheets

Cheatsheets for experienced Vue developers getting started with TypeScript.

Section 1: Setup

Prerequisites

  1. A good understanding of Vue.js
  2. Read the TypeScript support section in the Vue docs 2.x | 3.x

Vue + TypeScript Starter Kits

  1. Using the Vue CLI , you can select the TypeScript plugin to be setup in a new a Vue project.
# 1. Install Vue CLI, if it's not already installed
npm install --global @vue/cli

# 2. Create a new project, then choose the "Manually select features" option
vue create <my-project-name>
  1. Vite is a new build tool by Evan You. It currently only works with Vue 3.x but supports TypeScript out-of-the-box.

⚠ Currently in beta. Do not use in production.

npm init vite-app <project-name>
cd <project-name>
npm install
npm run dev

Section 2: Getting Started

Recommended ts.config setup

note: strict:true stricter inference for data properties on this. If you do not use it, this will always be treated as any

// tsconfig.json
{
    "compilerOptions": {
        "target": "esnext",
        "module": "esnext",
        "strict": true,
        "moduleResolution": "node"
    }
}

Usage in .vue files

Add lang="ts" to the script tag to declare TS as the lang used.

<script lang='ts'>...</script>

In Vue 2.x you need to define components with Vue.component or Vue.extend:

<script lang="ts">
import Vue from "vue";

export default Vue.extend({

  // type inference enabled
  name: "HelloWorld",
  props: {
    msg: String
  }
});
</script>

In Vue 3.x you can use defineComponent to get type inference in Vue component options

import { defineComponent } from 'vue';

const Component = defineComponent({
    // type inference enabled
});

Props

PropType can be used to annotate props with a particular object shape.

import Vue, { PropType } from 'vue'

<script lang="ts">
import Vue from "vue";

interface PersonInfo { 
  firstName: string,
  surname: string,
  age: number
}

export default Vue.extend({
  
  name: "InfoCard",
  props: {
    info: {
      type: Object as PropType<PersonInfo>,
      required: true
    }
  }
});
</script>

Alternatively, you can also annote your prop types with an anonymous function:

import Vue from 'vue'

<script lang="ts">
import Vue from "vue";

interface PersonInfo { 
  firstName: string,
  surname: string,
  age: number
}

export default Vue.extend({
  
  name: "InfoCard",
  props: {
    info: {
      type: Object as () => PersonInfo,
      required: true
    }
  }
});
</script>

Data Properties (Options API)

You can enforce types on Vue data properties by annotating the return data object:

interface Post {
  title: string;
  contents: string;
  likes: number;
}

export default Vue.extend({
  data(): { newPost: Post } {
    return {
      newPost: {
        title: "",
        contents: "",
        likes: 0
      }
    };
  }
});

It might be tempting to annotate your Vue data properties using as like this:

interface Post {
  title: string;
  contents: string;
  likes: number;
}

export default Vue.extend({
  data() {
    return {
      newPost: {
        title: "",
        contents: "",
        likes: 0
      } as Post // ❌ Avoid doing this
    };
  }
});

Note that type assertion 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.

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

vue's People

Contributors

chiubaca avatar roninii avatar swyxio avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue's Issues

Docs re-organisation

I've been thinking about how to best organise the docs. Currently there is clear divide between Vue 3 & Vue 2 I think it may be better to split the docs by Vue APIs for the following benefits.

  • ✅ This follows a similar structure to the Vue docs.
  • ✅ API examples are grouped together.
  • ✅ Should make navigating this cheatsheet easier for users (I know it would help me!).

However

  • 😕 We may have to explain some subtle caveats, gotachas during this transition between v2.x -> 3.x.

So I'd like to propose the following structure for this repo to look something like this, with some ideas of sections within each page:

README.md

  • Table of contents
  • Intro to cheatsheet
  • Overarching topics
  • Links to other resources

composition-api.md

  • Intro, setting up, why use composition API with TS.
  • typings for props,ref ,reactive, computed and other hooks.

options-api.md

  • Intro, setting up, why use options API, caveats of using TS with options API.
  • typings for data, methods, computed and other properties.

class-components.md

  • Intro, setting up, why use class component & decorators + TS.
  • typings for data, methods, computed and other properties.

Later down the line we can also start to have separate pages for Vuex and Vue Router potentially?

a few suggestions from someone using Vue + TypeScript every day for the last six months

  1. Use class-based components, not Vue's proprietary data shape that gets passed to Vue.extend. (at least for Vue 2)

  2. For Vuex support (types on your action / mutation payloads), use https://github.com/championswimmer/vuex-module-decorators.

  3. Put "vetur.experimental.templateInterpolationService": true in your VS Code settings to get TypeScript analysis on your <template> in .vue files. This only works inside VS Code with Vetur installed - vue-cli-service build won't show you type errors in your <template>.

  4. Don't forget that @someEvent='someEventHandler' isn't type safe. This is the only major area where Vue and TypeScript don't play nice and you end up with a black hole of untyped data coming into your application.

  5. Unrelated to Vue - verify the data coming into your app using IO-TS: https://github.com/gcanti/io-ts

  6. For linting, use ESLint + Prettier. Rather than wrestling with the setup, just use the Vue CLI (or run vue ui) and then choose to add TypeScript support to your project when initially creating it and choose ESLint + Prettier. @ts-ignore is banned by default. To change that, modify your eslintConfig.rules in your package.json file. Here's mine:

  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended",
      "@vue/typescript/recommended",
      "@vue/prettier",
      "@vue/prettier/@typescript-eslint"
    ],
    "parserOptions": {
      "parser": "@typescript-eslint/parser",
      "ecmaVersion": 2020
    },
    "rules": {
      "no-debugger": 1,
      "@typescript-eslint/ban-ts-ignore": 0,
      "no-var": 1,
      "@typescript-eslint/no-array-constructor": 1,
      "@typescript-eslint/camelcase": 1,
      "@typescript-eslint/no-use-before-define": 0,
      "prefer-const": 1,
      "@typescript-eslint/no-inferrable-types": 1,
      "@typescript-eslint/no-this-alias": 1,
      "@typescript-eslint/no-unused-vars": 1,
      "@typescript-eslint/no-explicit-any": 0,
      "@typescript-eslint/no-empty-function": 0,
      "no-console": 0,
      "@typescript-eslint/no-non-null-assertion": 0
    }
  }

seeking maintainers

i don't do much Vue so this is really wide open - please let me know if you're keen on maintaining this!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.