搭建vue+Typescript工程

开发工具 vscode

众所周知,vue2+Typescript的开发体验很不好,不过为了尝鲜,咱还是可以搭一个小工程玩一玩,下面就是搭建工程的步骤,以及遇到的一系列坑点。

1. 创建一个vue工程

vue init webpack 项目名称<项目名字不能用中文>

现在我们就有一个vue项目了,下面我们就需要安装各种插件,让他支持Typescript.

2. 安装必要的插件

安装vue的官方插件

npm i vue-class-component vue-property-decorator --save
  • vue-class-component支持类风格的vue代码编写

  • vue-property-decorator依赖于vue-class-component并对其进行强化,新增了如下7个装饰器和一个函数:

    • @Emit
    • @Inject
    • @Model
    • @Prop
    • @Provide
    • @Watch
    • @Component (从 vue-class-component 继承)
    • Mixins (vue-class-component提供的mixins帮助函数)

// ts-loader typescript 必须安装

npm i ts-loader typescript tslint tslint-loader tslint-config-standard --save-dev
  • ts-loader Typescript的加载器,如果你是webpack3,请装3版本,比如3.5.0,如果你是webpack4,请装3以上的版本
  • typescript 显而易见
  • tslint 检查Typescript代码工具
  • tslint-loader tslint 加载器
  • tslint-config-standard JavaScript标准样式的TSLint配置

3. 配置webpack

修改webpack.base.conf.js文件

entry: {
    app: './src/main.js'
  },
resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      '@': resolve('src')
    }
  }

修改为

entry: {
    app: './src/main.ts' // main.js->main.ts
  },
resolve: {
    extensions: ['.js', '.vue', '.json', '.ts'],  // 增加.ts
    alias: {
      '@': resolve('src')
    }
  }

module.rules里增加如下配置

{
      test: /\.ts$/,
      exclude: /node_modules/,
      enforce: 'pre',
      loader: 'tslint-loader'
    },
    {
      test: /\.tsx?$/,
      loader: 'ts-loader',
      exclude: /node_modules/,
      options: {
        appendTsSuffixTo: [/\.vue$/],
      }
    },

4. 添加vue的声明文件

Typescript默认不支持.vue结尾的文件,所以我们在import vue对象时会找不到,为了能正确引用,我们需要创建一个垫片。
根目录下添加vue.shim.d.ts文件,内容如下

declare module "*.vue" {
  import Vue from "vue";
  export default Vue;
}

接下来需要添加进tsconfig.json文件的include中,这样就能正确找到vue对象了。

5. 添加tsconfig.json文件

tsconfig.json存在的目录即为Typescript项目的根目录,tsconfig.json文件中指定了用来编译这个项目的根文件和编译选项。
生成命令

tsc --init

上面命令的前提是你全局安装了Typescript,如果没有,请先执行这条命令

npm update -g typescript

tsconfig.json初始化配置为

tsconfig初始配置.jpg

修改tsconfig.json文件

{
  "include":[
    "src/**/*",
    "vue.shim.d.ts"
  ],
  "exclude":["node_modules"],
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "lib": [
      "dom",
      "es5",
      "es2015.promise"
    ],
    "allowJs": true,
    "strict": true,
    "baseUrl": "./",
    "paths": {
      "@/*":["src/*"]
    },
    "esModuleInterop": true,
    "experimentalDecorators": true,
  }
}

由于json文件不允许写注释,另辟一处,介绍一下各个属性的意思

{
  "include":[], // 编译包含哪些文件
  "exclude":[], // 编译排除哪些文件
  "compilerOptions": {  // 编译选项
    "target": "es5",    // 指定ECMAScript目标版本'ES3' (默认),'ES5',或'ES6'
    "module": "commonjs",  // 指定生成哪个模块系统代码
    "lib": [  // 编译过程中需要引入的库文件的列表
      "dom",
      "es5",
      "es2015.promise"
    ],
    "allowJs": true,  // 允许编译javascript文件。
    "strict": true,  // 严格模式
    "baseUrl": "./",  // 解析非相对模块名的基准目录。
    "paths": {  // 模块名到基于baseUrl的路径映射的列表
      "@/*":["src/*"]
    },
    "esModuleInterop": true,  // 支持CommonJS和ES模块之间的互操作性
    "experimentalDecorators": true,  // 实验性启用ES7装饰器支持。
  }
}

6. 修改src下.js文件为.ts

初始化的vue项目会在src目录下有一个main.js文件,在src/router目录下有一个index.js文件,我们将其修改为ts文件
main.js -> main.ts
index.js -> index.ts

7. 运行yarn start

项目运行成功,但是会报错,不怕,你马上就要成功了!

@号和.vue.png

这里是因为我们书写时省略了后缀名,而Typescript只能识别.ts结尾的文件,.vue结尾的文件,所以我们需要给他们加上.vue后缀名即可

import App from './App' -> import App from './App.vue'

然后,我们再运行一遍,就不会报错了。但是这时候,我们的代码还都只是js代码,下面我们就把他们改写为ts代码。

8. 修改.vue文件

  • 利用vue-class-component插件
    HelloWorld.vue中的js代码
<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

修改为

<script lang="ts">
import Vue from 'vue' // 必须
import Component from 'vue-class-component' // 必须

@Component
export default class HelloWorld extends Vue {
  msg: string = 'Welcome to Your Vue.js App' // 等同于data中的msg
}
</script>

到这里,我们的架子就已经初步搭建完成,当然这离完全体还有一段距离,不过,先让我们爽一爽,我们为它增加上生命周期,计算属性,方法等。

<script lang="ts">
  import Vue from 'vue'
  import Component from 'vue-class-component'

  @Component
  export default class App extends Vue {
    // 初始化数据
    msg = 123

    // 生命周期钩子
    mounted () {
      this.greet()
    }

    // 计算属性
    get computedMsg () {
      return 'computed ' + this.msg
    }

    // 方法
    greet () {
      alert('greeting: ' + this.msg)
    }
  }
</script>

大家可以自己试一试,看看效果。

  • 利用vue-property-decorator
    然后,我们在上面的基础上再来修改一下我们的ts代码
// 可以看到这里Vue和Component都可以从vue-property-decorator插件中获取
import { Vue, Component } from 'vue-property-decorator'

@Component
export default class HelloWorld extends Vue {
    // 初始化数据
    msg = 123

    // 生命周期钩子
    mounted () {
      this.greet()
    }

    // 计算属性
    get computedMsg () {
      return 'computed ' + this.msg
    }

    // 方法
    greet () {
      alert('greeting: ' + this.msg)
    }
}
</script>

ok,现在我们已经可以初步编写我们的ts代码了,但是,有时候还会报一些其他错误,这多半是我们装的插件不够。。。

9. 添加其他额外插件

修饰符报错.png

修饰符报错2.png

大家还记得TS里的修饰符么,当我们为一个变量添加修饰符时,就会报语法错误,这是因为js是不支持这种写法的,而我们原来的工程里只安装了eslint,所以为了兼容这种写法,我们需要给eslint增加tslint功能,那么怎么增加呢?
添加以下两个插件

npm i @typescript-eslint/parser --save-dev
npm i @typescript-eslint/eslint-plugin --save-dev

修改.eslintrc.js文件

parserOptions: {
    parser: 'babel-eslint'
  },

parserOptions: {
    parser: '@typescript-eslint/parser'
  },

至此,大功告成,大家已经可以愉快地编写ts代码了

10. 其他常见问题

  1. 引入第三方库
    Typescript中引入第三方库除了要引用库本身外,还需引用库的声明文件
    比如我想引入lodash库,那么我就要执行以下两条命令
npm i --save lodash
npm i --save @types/lodash

@types开头的就表示声明文件
大多数情况下,类型声明包的名字总是与它们在npm上的包的名字相同,但是有@types/前缀, 如果你需要的话,你可以在 https://aka.ms/types这里查找你喜欢的库。
当然,你引用的库很可能暂时没有声明文件,如果你还想用他的话就需要自己写声明文件了,不过这不在本章的讨论范围类,大家可以自己研究下。

  1. 不支持下划线语法
    有时候,接口返回的字段会是这样的
access_token

但是呢,我们的eslint默认要求所有变量遵循驼峰原则,即accessToken,这样的话,我们的编辑器就会报错,那么怎么解决呢?
我们找到根目录下的.eslintrc.js文件,他是负责eslint配置的,我们给他的rules对象增加一条属性

'camelcase':0

这样就关闭了eslint的驼峰检测了
ok,以上就是这篇要说的全部内容,如果,你已迫不及待,就打开vscode搭建一遍吧。

以下是一个已经搭建好的小demo
vue+typescript demo

参考链接/推荐阅读

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335