如何将Typescript与Vue.Js集成


几周前,我开始了一个新的Vue项目。 我的一位联合开发人员建议在项目上使用TypeScript:“它将帮助我们发现错误和错误,并且我们添加的越早,越容易”。 这是我第一次使用TypeScript进行开发。“

为什么使用TypeScript?

TypeScript主页:https://www.typescriptlang.org/index.html

首先,您现在应该执行TypeScript的操作。 TypeScript是一种与Java语法相同的语言。 TypeScript是我们所谓的Javascript超集。 这意味着您编写的每个Javascript代码都是有效的TypeScript代码,并且可以由TypeScript进行编译。 因此,您可以将TypeScript添加到您现有的Javascript项目中。 TypeScript的主要目标是提供可选的静态类型和类型推断。

// The variable x will be seen as a boolean
let x: boolean

// Here the type inference makes y as a boolean too
let y = true

您可以键入变量,函数参数,函数返回... TypeScript然后将对您的代码进行静态分析以检查危险的操作(根据类型)。 您可能会意外地尝试为变量分配错误的类型或访问未定义对象的属性。 最后一个问题在运行时发生很多,您没有检查对象是否不是null。 然后,代码崩溃了……

let x: boolean

/**
If you want to assign another a value with the wrong type
TypeScript will trigger an error. In my editor I have :
Assigned expression type "This is a string, not a bool" is not assignable to type boolean
**/
x = 'This is a string, not a bool'


/**
Here 'find' can return undefined if no correct document is found.
Therefore, accessing the property 'type' will trigger a runtime error
**/
const documents = [{type: 'Review'}, {type: 'Book'}]
const myArticle = documents.find(document => (document.type === 'Article'))

const myArticleType = myArticle.type

对于最后一个示例,在编译过程中将出现以下错误:

TypeScript strict null check error

希望本文能说服您使用TypeScript。 如果您是新手,建议您阅读手册

现在让我们看看如何在Vue项目中安装它。
在Vue中使用TypeScript
安装TypeScript在一个新项目上

如果启动新项目,则可以使用Vue CLI进行自己的设置,然后在选项中选择Typescript。

如何将Typescript与Vue.Js集成

然后输入“yes”以使用类样式的组件语法。 稍后我们将介绍为什么您应该使用此语法。

如何将Typescript与Vue.Js集成

在现有项目上

如果将其添加到现有项目中,仍然可以使用NPM添加TypeScript:

npm install -g typescript

而且,您可以检查TypeScript配置的建议配置。

在Vue中使用TypeScript的代码语法

首先,让我们告诉我们的Vue编译器,Javascript将是TypeScript。 在Vue文件的script标签中,执行以下操作:

<template>
</template>

<!--Add lang="ts" to specify it's TypeScript-->
<script lang="ts">
</script>

<style>
</style>

然后,我们需要将语法修改为TypeScript友好的。

在安装期间(通过Vue CLI),我建议您使用类样式的组件语法。 但是存在其他语法。 在Vue中,主要有3种语法:Options API,Composition API和Class API。 我建议您使用后者。 但是,我们将看到如何将TypeScript与它们一起使用。

Options API

此语法是Vue的基本语法。 但是您需要以不同的方式导出组件。 通常的导出没有启用类型推断:

<template>
</template>

<script lang="ts">
export default {
  //No type inference
  components: {},
  data() { return {} },
  computed: {},
  created() {},
  methods: {}
}
</script>

<style>
</style>

因此,您将需要使用Vue.extend语法导出Javascript:

<template>
</template>

<script>
import Vue from 'vue';

// Note the Vue.extend
export default Vue.extend({
  //Type inference
  components: {},
  data() { return {} },
  computed: {},
  created() {},
  methods: {}
})
</script>

<style>
</style>

在我的项目开始时,我们在Vue文件中使用options API。但是我们在TypeScript方面遇到了一些问题,因此决定使用Class API。坦白地说,事后看来,我认为一些问题是由于我们未正确使用TypeScript与选项API一起使用。例如,不键入函数将返回。现在,随着TypeScript的最新更新,我不再能够重现这些错误。

但是我仍然建议您使用类样式的组件进行编码,因为您可能像我一样对Options API遇到一些小问题。此外,网络上还有更多带有类样式组件的示例。

Composition API

该语法是Vue 3的新语法。该语法在构建时考虑了TypeScript集成。因此,Composition API将提供更好的TypeScript支持,而且我认为您不必为了使用TypeScript而更改语法。如果要在Vue 2中使用此语法,则可以使用composition-api软件包。 Vue 3将于2020年初发布,目前处于(pre)Alpha版本。如果您有时间研究这种新语法,建议您开始使用它进行编码,以熟悉Vue 3。

但是,如果您希望在使用composition API之前等待正式发布,请查看最后可用的语法。

Class API

引入类API的主要目的是提供一种具有更好TypeScript推理支持的替代API。

要使用Class API语法,您将需要安装软件包vue-class-component(已随Vue CLI一起安装)。

然后使用以下语法创建Vue组件:

import Vue from 'vue'
import Component from 'vue-class-component'

@Component({
  props: {
    myProp: {
      type: String
    }
  }
})
export default class HelloWorld extends Vue {
  myData: {name: string} = {name: 'test'}

  // computed are declared with get before a function
  get myComputed(): string {
    return this.myData.name
  }

  created() {}

  // methods are just functions
  myMethod(): boolean {
    return false
  }
}

您将很快习惯这种语法!

这种语法的一个优点是,您可以按功能重新组合 'methods' 和 'computed'(composition API也为此目的而构建)。

import Vue from 'vue'
import Component from 'vue-class-component'

@Component({})
export default class HelloWorld extends Vue {
  // Autocomplete functionality
  get computedRelatedToAutocomplete() {
    ...
  }
  methodRelatedToAutocomplete() {
    ...
  }

  // Search Functionality
  get computedRelatedToSearch() {
  ...
  }
  methodRelatedToSearch() {
  ...
  }
}

Vue 2完全支持软件包vue-class-component。

我们可以做的另一项改进是使用软件包vue-property-decorator。 该软件包也由Vue CLI安装。

有了它,甚至道具也将在组件的定义内:

import { Component, Prop, Vue } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
  // The props are defined here with the annotation @Prop()
  @Prop()
  private msg!: string;

  myData: {name: string} = {name: 'test'}

  // computed are declared with get before a function
  get myComputed(): string {
    return this.myData.name
  }

  // methods are just functions
  myMethod(): boolean {
    return false
  }
}

缺点:Class API仍然不能与TypeScript完美配合,在Vue 3中将由Composition API代替。在Vue 3发布之后,我强烈建议您使用Composition API。

但是目前,这是我们最好的解决方案!从一种表示法更改为另一种表示法并不那么复杂。您可以一次更改一个文件,而仍然使用另一种语法运行其他文件。那就是我们从选项API更改为类API所做的。即使到了今天,我们仍然拥有带有选项API语法的旧文件(我们正在逐步迁移)。

实际上,您也可以同时使用Vue实现一个文件的TypeScript(如果将其添加到现有项目中)。您获取一个Vue文件,然后在script标签内添加lang =“ ts”。然后,修改组件以使用Class API并修复TypeScript发现的潜在错误。真的很简单!

技巧和小贴士

在Vue中输入道具

在您的项目中,您将要键入道具。确实,您为道具定义的类型应该是Vue类型中的一种。您可以使用布尔值,字符串,数组,但不能使用自制类型。

import Vue from 'vue';

type MySuperType = {
  name: string
  age: number
}

export default Vue.extend({
  props: {
    mySuperProps: {
      type: MySuperType, // Will not work
      required: true
    }
  }
})

您将需要使用另一种语法:

import Vue from 'vue';

type MySuperType = {
  name: string
  age: number
}

export default Vue.extend({
  props: {
    mySuperProps: {
      type: Object as () => MySuperType,
      required: true
    }
  }
})

在Vuex中使用Typescript

如果您计划在项目中使用Vuex,则还可以输入商店。 在有关Vuex和TypeScript的本文中,您将找到有关如何键入商店以及如何通过Class API使用组件内的动作/状态/获取器的详细说明。

可为空的对象的访问属性

有时您将有一个可为空的对象。 在访问对象的属性之前,您需要检查对象是否不为null。 但是您无法在任何地方进行此检查。 它必须靠近该属性的访问权限。

以下是一些可为空的对象的示例/技巧:

import { Component, Prop, Vue } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
  value: null | {test: string} = null
  setValue() {
    this.value = {test: 'hello'}
  }

  /**
  * this.value can be null,
  * we cannot access the property test on null
  *
  * An error will be triggered
  */
  methodWithTypeError() {
    this.value.test //error
  }

  /**
  * checking that value is not null before accessing property
  * will tell TypeScript that the variable is safe
  *
  * No error will be triggered
  */
  methodWithNoError() {
    if(this.value === null) {
      return
    }
    this.value.test
  }

  /**
  * When performing its analysis TypeScript will not check the whole code
  * Therefore, even if we have checked this.value before
  * it will still see it as null inside the map function
  *
  * An error will be triggered
  */
  methodWithErrorWhereItShouldBeOK() {
    {
      if(this.value === null) {
        return
      }
      const array = [1, 2, 3]
      array.map((arrayValue: number) => {
        return arrayValue + this.value.test //error
      })
    }
  }

  /**
  * Here by assigning this.value.test to
  * another variable just after the null test,
  * TypeScript will infer its type as not null
  *
  * No error will be triggered
  */
  fix() {
    {
      if(this.value === null) {
        return
      }
      let test = this.value.test
      const array = [1, 2, 3]
      array.map((arrayValue: number) => {
        return arrayValue + test
      })
    }
  }
}

如何将Typescript与Vue.Js集成

此类问题的另一种解决方案是使用lodash函数get,如果对象为null,则返回默认值。 但是,使用此解决方案,您在访问属性时无需使用TypeScript。

我花了一些时间来习惯TypeScript。 一开始,我不了解TypeScript的全部功能,并认为这是额外的工作。 但是随着时间的流逝,我开始习惯于TypeScript,并且我的Javascript代码更加结构化。 现在,它更易于开发,尤其是与其他开发人员一起编码时:TypeScript允许您为对象赋予形状,从而使其他对象更容易理解。

希望本文能说服您使用TypeScript,并且对您有所帮助。

linuxboy的RSS地址:https://www.linuxboy.net/rssFeed.aspx

本文永久更新链接地址:https://www.linuxboy.net/Linux/2019-11/161514.htm

相关内容