第一个使用 TypeScript 的 Vue3 应用程序

354 阅读7分钟

Vue 3 已经使用TypeScript从头开始​​重建。从 Vue2 开始,Vue 已经支持 TypeScript,现在仍然支持。然而,这些天来,我感觉到了使用 TypeScript 开发 Vue 3 应用程序的某种炒作和兴趣。

毫无疑问,使用 TypeScript 开发 JavaScript 应用程序是救命稻草。TypeScript 除了带来许多好处外,还提供类型安全。你会很开心,你的 IDE 也会很开心,当然,它会让 JavaScript 编写变得更加有趣和健壮。

本文将带您一步步指导创建 Vue 2 应用程序、添加 TypeScript 支持、将应用程序升级到 Vue 3 RC 5、编译应用程序、修复一些常见的编译时错误,最后确保应用程序在浏览器中运行。

如果您是 TypeScript 新手,我建议您观看由杰出的 [Maximilian]从头开始​​学习 TypeScript 的免费课程

施瓦茨米勒]( academind.com/ )。

另一方面,如果您想要本文随附的源代码,请随时在此GitHub Repo访问它。

免责声明 - 本文适用于您想要升级到 Vue 3 并添加 TypeScript 的现有 Vue 2 应用程序,以及任何新应用程序。

🔗演示

让我们从创建一个 Vue 2 应用程序开始,并完成必要的步骤。

🔗创建新应用

正如副标题所暗示的,我们将使用 Vue CLI 创建一个 Vue 2 应用程序。

🔗第 1 步:安装 @vue/cli NPM 包

打开终端窗口并运行以下命令:

npm install -g @vue/cli
🔗第 2 步:创建一个新的 Vue 2 应用程序
vue create vue-ts

\

default preset出现提示时选择。CLI 为您构建文件,并为应用程序初始化一个 Git 存储库。

🔗第 3 步:运行应用程序

运行应用程序以确保其正常工作:

cd vue-ts
npm run serve

\

您现在应该有一个正在运行的应用程序!

🔗添加 TypeScript 支持

让我们运行以下命令为我们的应用程序添加 TypeScript 支持。

vue add typescript

\

上面的命令下载并安装@vue/cli-plugin-typescript插件,为我们的应用程序带来 TypeScript 支持。

安装后,系统会询问您几个问题,如图 1所示。

agregando 打字稿

\

安装问题
使用类风格的组件语法? 是的
将 Babel 与 TypeScript 一起使用? 是的
将所有 .js 文件转换为 .ts? 是的
允许编译 .js 文件吗? 是的
跳过所有声明文件的类型检查? 是的

\

在插件添加到应用程序的众多内容中,我想指出tsconfig.json应用程序文件夹根目录下的文件。TypeScript 使用此文件来自定义编译过程,并让您有机会这样做,以满足您的需求。以下设置是 Vue 团队推荐的。但是,您可以随意添加或更改您认为合适的内容。

有关此文件中可供您使用的所有选项的完整列表,请点击此链接tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

\

最后,确保在继续之前将您的更改提交到 Git。

🔗将应用升级到 Vue 3

现在该应用程序支持使用 TypeScript 语法编写 Vue 组件,让我们继续,将应用程序升级到 Vue 3。

🔗第 1 步:添加 Vue-Next 插件

打开一个终端窗口并导航到我们应用程序的根文件夹。然后,运行以下命令:

vue add vue-next

\

该命令下载并安装vue-cli-plugin-vue-next插件以将应用程序升级到 Vue 3。

图 2 显示了 CLI 执行升级所采取的所有步骤。

agrega-vue-next

打开/package.json文件,并确保dependenciesdev-dependencies部分与以下类似:

 "dependencies": {
    "core-js": "^3.6.5",
    "vue": "^3.0.0-rc.5"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.4.0",
    "@vue/cli-plugin-eslint": "~4.4.0",
    "@vue/cli-service": "~4.4.0",
    "@vue/compiler-sfc": "^3.0.0-rc.5",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^7.0.0-alpha.0",
    "vue-cli-plugin-vue-next": "~0.1.3"
  },

\

vue-next插件会自动检查您的应用程序文件,并将它们转换为与 Vue 3 语法兼容。

🔗第 2 步:修复警告和错误

此时,如果您编译应用程序,您将看到一些警告和错误。这些主要与在 Vue 3 中使用 TypeScript 有关。让我们一一解决。

运行以下命令在浏览器中编译并启动应用程序:

npm run serve

\

输出如下所示:

警告

warning  in ./node_modules/vue-class-component/dist/vue-class-component.esm.js
"export 'default' (imported as 'Vue') was not found in 'vue'

warning  in ./node_modules/vue-class-component/dist/vue-class-component.esm.js
"export 'default' (imported as 'Vue') was not found in 'vue'

warning  in ./node_modules/vue-class-component/dist/vue-class-component.esm.js
"export 'default' (imported as 'Vue') was not found in 'vue'

warning  in ./node_modules/vue-class-component/dist/vue-class-component.esm.js
"export 'default' (imported as 'Vue') was not found in 'vue'

warning  in ./node_modules/vue-property-decorator/lib/vue-property-decorator.js
"export 'default' (reexported as 'Vue') was not found in 'vue'

\

错误

TS1238: Unable to resolve signature of class decorator when called as an expression.
  Type '<VC extends VueClass<any>>(target: VC) => VC' is not assignable to type 'typeof HelloWorld'.
    Type '<VC extends VueClass<any>>(target: VC) => VC' provides no match for the signature 'new (): HelloWorld'.
    33 | import { Component, Prop, Vue } from 'vue-property-decorator';
    34 | 
  > 35 | @Component
       | ^^^^^^^^^^
    36 | export default class HelloWorld extends Vue {
    37 |   @Prop() private msg!: string;
    38 | }

ERROR in src/components/HelloWorld.vue:36:41
TS2507: Type 'typeof import("/Users/bhaidar/projects/vue-ts/node_modules/vue/dist/vue")' is not a constructor function type.
    34 | 
    35 | @Component
  > 36 | export default class HelloWorld extends Vue {
       |                                         ^^^
    37 |   @Prop() private msg!: string;
    38 | }
    39 | </script>

\

警告和错误表明 TypeScript 无法消化HelloWorld以 Vue 2 的旧 TypeScript 语法编写的组件。让我们重构该组件以使用 Vue 3 中的最新 TypeScript 语法。

目前,/components/HelloWorld.vue组件的脚本块定义如下:

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

@Component
export default class HelloWorld extends Vue {
  @Prop() private msg!: string;
}
</script>

\

首先,注意元素lang="ts"上属性的使用。<script>这定义了 TypeScript 代码块而不是 JavaScript 代码块。

让我们将此代码替换为:

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

export default defineComponent({
  name: 'HelloWorld',
  props: {
    msg: {
      type: String,
      required: false,
    },
  },
});
</script>

\

该代码使用了新的defineComponent全局方法。此方法允许 TypeScript 正确推断 Vue 组件选项中的类型。

defineComponent方法接受输入参数对象。它可以是 Options API 对象或 Composition API 对象。

您可以通过查看我关于Vue 3 Composition API 的文章了解更多关于 Options API 和 Composition API 的信息,您真的需要它吗?

现在该HelloWorld组件已被重构。让我们继续,重构App.vue组件以使用 Vue 3 中新的 TypeScript 语法:

<script lang="ts">
import { defineComponent } from 'vue';
import HelloWorld from '@/components/HelloWorld.vue'

export default defineComponent({
  name: 'App',
  components: {
    HelloWorld
  },
});
</script>

\

让我们通过发出以下命令来运行应用程序:

npm run serve

\

哇!更多错误和警告!

Argument of type 'typeof import("/.../vue-ts/
node_modules/vue/dist/vue")' is not assignable to parameters of type 'PublicAPIComponent'.

Type 'typeof import("/.../vue-ts/node_modules/vue/dist/vue")' is not 
assignable to type 'ComponentOptionsWithObjectProps<any, any, any, 
any, any, ComponentOptionsMixin, ComponentOptionsMixin, EmitsOptions, 
string, Readonly<{ [x: string]: any; }> | Readonly<...>>'.
...

\

__ 导入 Vue 组件__

上面的错误是针对文件中的第 2 行生成的main.ts

import { createApp } from 'vue';
import App from './App.vue'
       ^^^
createApp(App).mount('#app')

\

Typescript 和 ES 6 一样,通过使用关键字importexport来支持模块。只要您在 TypeScript 中编写模块,即以 .ts结尾的模块文件,那么您将被覆盖。

上面的错误表明 TypeScript 无法导入App组件,就好像App.vueTypeScript 不理解返回的模块一样。

解决方案?在应用程序的根文件夹中定义shimdelation文件。 该文件的扩展名为.d.ts. 它基本上使工具更容易知道如何处理*.vue文件,也称为单文件组件 (SFC)。

在您的应用程序的根文件夹中找到该shim-vue.d.ts文件,并将其内容替换为以下内容:

declare module "*.vue" {
  import { defineComponent } from "vue";
  const component: ReturnType<typeof defineComponent>;
  export default component;
}

\

*.vue该代码为每个以(SFC)结尾的文件声明了一个 TypeScript 模块。

TypeScript 会将这样的模块消化为具有以下内容:

  • defineComponent全局方法的导入语句
  • component类型变量的声明defineComponent
  • 最后,component变量的默认导出

有了上面的 shim 文件,TypeScript 就可以将任何 Vue 组件视为一个定义良好的模块。

🔗运行应用程序

现在您可以安全地运行应用程序,因为它知道它将在浏览器中成功运行。

运行以下命令以启动应用程序:

npm run serve

\

导航到浏览器中的 URL http://localhost:8080,您应该能够看到使用 TypeScript 新创建的 Vue 3 应用程序的默认主页,如下 图 3所示。

vue3-typescript-pagina-inicio

🔗将 Composition API 与 TypeScript 一起使用

现在该应用程序是 TypeScript 感知的,让我向您展示如何利用 Composition API 和类型安全性来定义具有类型参数的函数。

HelloWorld将组件脚本的内容替换为以下内容:

import { defineComponent } from 'vue';

export default defineComponent({
  name: 'HelloWorld',
  props: {
    msg: {
      type: String,
      required: false,
    },
  },
  setup(props) {
    const printMsg = (msg: string) => console.log(`The message is: ${msg}`);

    return {
      printMsg,
    };
  },
});

\

请注意代码如何使用带有类型参数的 Composition API 定义新函数。该参数被命名msg并具有数据类型string

🔗结论

无论您是升级现有的 Vue 2 应用程序,还是开始一个新的应用程序,本文都提供了将 TypeScript 添加到应用程序、升级到 Vue 3、修复所有警告和错误并最终成功运行应用程序的分步方法在浏览器中。

这是您使用 TypeScript 构建 Vue 3 应用程序的垫脚石。下一步是让自己更加熟悉 TypeScript。

祝你快乐!