阅读 699

any 之殇

ts 在这两年如同星火燎原之势席卷前端,作为在失业边缘颤抖的码畜,生怕不会 ts 被市场淘汰。趁着 vue3.0 出来之前的间隙赶紧学习学习,以便 3.0 出来之后能够直接使用 vue3.0 + ts 撸代码。

小刚老师

一键安装

使用命令vue create,选择Babel, TS, Router, CSS Pre-processors, Linter。(虽然暂时没用过单元测试,但是单元测试还是挺重要的以后会学的。)

选好之后一路回车,但是需注意选择linter的时候,选择ESLint,因为 ts 官方已经宣布正式放弃 TSLint 转向生态更好的 ESLint 了。我这里选择的是Standard代码规范。

回车后脚手架会帮我们自动生成项目文件并自动安装配置中的依赖,最终生存如下文件目录:

  public // 可以放静态资源不会被打包
    index.html // 项目首页,可以在此页面已 cdn 的方式引入其他js css文件
  src // 当前项目文件
    assets // 静态资源存放需要被打包
    components // 组件存放处
    views // 当前项目页面存放处
    app.vue // 全局路由页面
    main.ts // 入口js
    routet.ts // 路由配置
    shims-tsx.d // 支持jsx
    shims-vue.d // 支持vue
    .browserslistrc // 要兼容的目标浏览器的范围
    .eslintrc.js // eslint 配置
    babel.config.js // babel 配置
    tsconfig.json // ts 编译配置
    package.json // webpack 配置
复制代码

最后运行npm run serve命令项目就能跑起来了。

初步上手

项目使用vscode开发,需安装ESLintVetur插件。

脚手架生成的项目配置很简单,我们可以根据自己的需要进行一些自定义配置。

首先我们在根目录下创建一个vue.config.js文件,这是vue-cli3.0默认的webpack配置文件。

然后在根目录创建两个文件.env.dev.env.prod,用来存放开发和生产环境的环境名称和接口地址。

然后修改package.json文件的script配置如下:

"scripts": {
  "serve": "vue-cli-service serve --mode dev",
  "build": "vue-cli-service build --mode prod",
  "lint": "vue-cli-service lint"
},
复制代码

其中--mode dev便指向了.env.dev文件,--mode prod指向了.env.prod文件,对应两个命令分别创建开发环境变量和生存环境变量。这样就可以在项目代码中使用process.env.NODE_ENVprocess.env.BASE_URL访问环境名称和接口地址了。

然后安装插件npm i element-ui npm i axios

然后我们在src目录下创建一个api文件夹,在api文件夹下创建axios.ts文件配置axios拦截器,创建index.ts文件存放项目接口方法。

然后在src目录下创建untils文件夹,存放项目使用的公共方法和一些无处安放的小工具。

然后终于可以愉快的玩耍了,写写写,写了一堆any

any之殇

下面是一个组件实例:

import { Component, Vue, Prop, Watch } from 'vue-property-decorator'
import { State, Getter } from 'vuex-class'
import { count, name } from '@/person'
import { componentA, componentB } from '@/components'

@Component({
  components:{ componentA, componentB},
})
export default class HelloWorld extends Vue{
  // props
  @Prop({ default: 'default value', type: String }) propA!: string // 注意prop需要断言!为一定存在,否则会报错
  
  // 原data中的属性
  message = 'Hello'
  
  // 原computed中的计算属性
  private get reversedMessage (): string {
    return this.message.split('').reverse().join('')
  }
  private set setMessage (newV: string): void {
    this.message = newV
  }

  // method
  private changeMessage (): void {
    this.message = 'Good bye'
  }
  private getName(): string {
    let storeName = name
    return storeName
  }
  
  // watch
  @Watch('message')
  private showChange (newV) {
    // ...
  }
  
  // 生命周期
  private created ():void { }
  private mounted ():void { }
  private updated ():void { }
  private destroyed ():void { }
}
复制代码

其他钩子的装饰器参考 vue-property-decorator

Mixins 钩子装饰器参考 vue-class-component

any之殇

笔者在尝试用 ts 写了一个小 demo 之后,便着手将最近新开发的一个小项目从 js 转为 ts 。由于公司新需求下来了,为了能尽早开发新需求需要将项目尽快跑起来,便在很多地方直接用 any 类型声明了。等到得空改写 any 时,一查项目中竟然有 100+ 的 any 类型。然后我便怂了,这么多 any 得改到猴年马月啊!于是我便请教大佬 ts 中接口函数的返回值是不是可以不用声明类型,大佬回:

any之殇

说实话用 ts 的原因我之前也看过很多了,大佬这么说我还是很受伤的,我只是不太明白接口函数返回值声明类型的意义用处何在。于是暗自下决心要把 ts 用到极端,所有能不用 any 的地方全都不用 any

经过仔细查看我发现这些 any 大都是接口函数的形参实参或者返回值。于是就给每个接口函数的参数和返回值都定义了类型:

给使用返回值的地方也加上类型:

有了这些类型声明,有些数组变量在使用的时候就不用手动为子项声明类型了,因为他可以自动推导出数组的子项的类型,例如这个map方法回调函数的参数和返回值被自动推导出来:

所有能不用 any 的地方我都修改了,最后只剩下一些我实在不知道怎么定义类型的,一般这些类型都是 dom 上的元素调用了插件如 element-ui 的方法:

由于涉及公司项目源码不能外泄,所以我就做了个小 demo 放到了 github 上供大家参考下里面的配置,项目仓库地址

最后,推荐些学习 vuetypescript 的好文:

关注下面的标签,发现更多相似文章
评论