Vue 现在非常火热,我之前就一直在考虑用它做一个大型项目。所以当机会出现时,我毫不犹豫地开始了。但有一个小问题——项目的要求之一是用 TypeScript 编写。一开始,我非常担心如何开始这个组合,但 vue-cli 让它变得非常简单。
如果我说这段旅程非常顺利,那是在撒谎。期间也遇到了一些挫折,盯着屏幕看了几个小时,还拍了几下桌子,但在使用 Vue + TypeScript 一个多月后,我可以说这一切都是值得的——如果我以后还要用 Vue 开发另一个应用程序,我不会在没有 TypeScript 的情况下进行。
先决条件
本文介绍了 Vue 和 TypeScript 的结合使用,并假设您对两者都有一定的基本了解。如果您还没有机会尝试使用它们,并且对此感到好奇,Vue 提供了一个很棒的指南,并且 TypeScript 文档 是一个很好的起点。
我们需要全局安装 vue-cli,以便快速启动 Vue 项目。在您的终端中运行以下命令来安装 vue-cli
npm install -g @vue/cli
安装完成后,就可以开始了。如果您还没有安装 TypeScript,也不需要提前安装,因为当您启动新项目并在其中选择 TypeScript 时,vue-cli 会为您处理。
开始
现在我们已经安装了 vue-cli,要开始一个 Vue + TypeScript 项目,只需运行 vue create
即可。创建新项目时,选择 TypeScript,然后就可以开始了。
vue create <app-name>
以下是项目启动后的结果

vue-cli 还允许我们选择 Babel 与 TypeScript 配合使用以进行 polyfills、CSS 预处理器、代码检查器、单元测试库(我选择了 Jest,加油 Jest!)以及其他配置。您甚至可以将您的选择保存在预设中,以便以后在其他项目中使用。
以下是配置项目时会遇到的实用问题

我想提一点的是,vue-cli 3.0 带有一个用户界面,这使得创建新项目变得更加容易。在终端中运行 vue ui
,vue-cli 会打开一个 UI,您可以在其中设置新项目。
盒子里的东西
vue-cli 完成后,我们会得到一个很好的应用程序目录结构,其中所有设置都已完成。
- tsconfig.json: 这个文件已经全部设置好了,我们可以根据需要进行编辑。
- shims-vue.d.ts: 这些 shims 已经设置好,可以帮助 TypeScript 理解导入的
.vue
文件(单文件组件)。 - vue-property-decorator: 如果您选择使用类样式组件,vue-cli 会添加此插件,以便我们可以使用各种装饰器。这非常方便,并使代码更易于阅读。
- 类组件: 如果您选择使用它们,vue-cli 会为您做好准备。请记住,您仍然需要注册路由钩子,以便类组件可以解析它们。
Sass 设置
我需要设置的一件事,并且希望它能默认包含在内,是共享的 Sass 部分文件。为了避免在每个组件中都导入我的 Sass 变量和 mixin,我必须在 vue.config.js
中加载它们。shared.scss
是导出应用程序中使用的所有变量和 mixin 的文件。
这是我最终使用的 Sass 配置
chainWebpack: (config) => {
config
.module
.rule('vue')
.uses
.get('vue-loader')
.tap(({ loaders, loaders: { scss }, ...options }) => ({
...options,
loaders: {
...loaders,
scss: [
...scss,
{
loader: 'sass-resources-loader',
options: {
resources: [
'./src/styles/shared.scss',
],
},
},
],
},
}));
Vue 属性装饰器
vue-property-decorator 包公开了 Vue 属性,并使它们可以作为装饰器使用。在我的应用程序中,我最终只使用了 @Component
、@Prop
、@Watch
,但还有其他一些装饰器,例如 @Emit
、@Inject
和 @Model
,如果大量使用,它们会使代码变得冗长。
Vuex
Vuex 有类型定义……就这些!Vuex 支持 TypeScript,一开始我甚至不知道。我开始寻找将 Vuex 与 TypeScript 结合使用的正确方法,偶然发现了 Alex Jover Morales 在 egghead.io 上的课程,主题是使用 Vuex 和 TypeScript 进行 Vue.js 状态管理。它帮助我了解了使用 TypeScript 时管理 Vuex 状态的正确方法。
例如
// actions.ts
import { ActionTree } from 'vuex';
import { RootState, ModuleState } from '@/types';
const actions: ActionTree<ModuleState, RootState> = {
// all your actions go here
};
Vuex-class
这是我一开始不知道存在的东西,但现在希望我早点发现它。我几乎为所有内容都创建了 getter,但这感觉不太对。我开始寻找更好的方法来做到这一点,并找到了 Francesco Vitullo 的一篇 有趣的文章,它为我澄清了一些事情。在那里我了解到 vuex-class,它为所有 vuex 映射器提供装饰器。
因此,现在,我不再需要为简单地访问状态中的属性编写新的 getter,我可以这样做
import {
State,
} from 'vuex-class'
@Component
export class MyComp extends Vue {
@State(state => state.bar) stateBar
}
使用 VS Code 的开发体验
使用 TypeScript 后,在 VS Code 上的编码体验好多了。不再需要来回切换以检查我在 mutation-types.ts
中声明的 mutation 类型,因为 VS Code 可以识别它们,并在键入时建议正确的类型。

修改 mutation 中的状态也是如此——使用 TypeScript,编辑器知道我的状态结构是什么样子,并建议正确的属性。
如果您使用的是 VS Code,我强烈建议使用 Vetur 插件,因为它提供了 Vue 工具,并自带其他一些功能,例如语法高亮(这在 Vue 单文件组件中效果很好)和代码检查。
最后的想法
就像 JavaScript 生态系统中的其他一切一样,Vue + TypeScript 还有很长的路要走。例如,我无法使用 vuelidate,因为它 没有类型定义。但幸运的是 vee-validate 提供了一种解决方法,因此我不必走上自己编写类型定义的艰难道路。
总之,我发现开发体验变得更加流畅,并且当您使用 TypeScript 时,VS Code 完全变成了一个不同的工具。我不需要过多赞美 Vue——它非常容易上手,可以立即开始构建,并且可以节省您花费在理解框架内部工作原理上的时间。
文章不错,谢谢。只有一点,如何像这样加载你的sass文件(配置似乎更简单)
这会有区别吗?
@flwer 是对的,这对mixin和变量非常有效,然后你可以简单地让app.vue或任何你称之为根组件的文件具有非作用域样式,并在那里导入你的其他基础样式。