Typescript+Vue体验与总结

1,562 阅读3分钟

1.TypeScript

TypeScriptJavaScript 的超集,就是在 JavaScript 上做了一层封装,封装出 TypeScript 的特性,最终代码可以编译为 JavaScript

1.1 静态类型

TypeScript 的核心就是静态数据类型。在js中,我们定义函数时并不会去声明他的参数类型或者返回类型,那这样其他人调用这个函数就很蛋疼了。

export const fetch = function (url, params, user) {
    //dosomething
    return http(options).then(data => {
    return data
  }).catch(err => {
    return err
  })
}

而如果我们使用TypeScript来定义这个函数:

export const fetch=function(url: string|object, params?: any,use?: User):Promise<object | Error>{
	return http(options).then(data => {
    return data
  }).catch(err => {
    return err
  })
}

使用TS定义的函数,就包含了很多信息:

  • url可能是stringobject类型;
  • params是可以不传的,也可以传递任意类型;
  • user要求是User类型,也可以不传;
  • 返回一个PromisePromise的值可能是object,也可能是Error

1.2 类型声明

---基础类型---
let a: number
let b='hello'   //有默认值的话,就不需要声明类型,ts自动推导;
let c: [string,number]   //原数组,数组的元素类型为string和number;
let d: {name: string}={name: 'macycle'}

---复杂类型---
let list1: number[] =[1,2,3]   
let list2: Array<number>=[1,2,3]   //number类型的数组
let notType: any=3  //any类型可以自由赋值

---高级类型---

let foo:string | number=1   //联合类型,foo的类型可以是string或number
(foo as string//类型断言,强制使用兼容类型中的某一类型

2.在vue中使用TypeScript

2.1 让Typescript识别Vue、JSON文件

因为Typescript默认不能识别.vue文件,导致在引用.vue文件时,提示加载错误。所以需要自己新建一个 .d.ts 文件添加以下内容。这告诉Typescript.Vue结尾的导入的任何东西都与Vue构造函数本身具有相同的形状。

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

Typescript也不能识别.json类型的配置文件,因此也需要在*.d.ts文件中声明。

// .d.ts
declare module "*.json" {
  const value: any;
  export default value;
}

2.2 使用装饰器定义组件

在vue项目中使用Typescript定义vue时,一般是使用class的形式。使用这种方式需要使用装饰器来定义组件。这种定义方式还依赖于额外的两个包vue-class-componentvue-property-decorator。这两个包可以让我们使用装饰器来定义组件的方法、属性等内容。

2.3 Computed、Data、Methods

class定义的vue中,取消了datamethods属性,datamethods当做类的属性和方法,直接定义在class中。

import {Component} from 'vue-property-decorator';
@Component
export default class One extends Vue{
count: number=1;
increment(){
    //dosomething
}
}

在这里computed可以写在Component中:

import {Component} from 'vue-property-decorator';
@Component({
    computed:{
        do(){
            //dosomething;
        }
    }
})
export default class One extends Vue{}

但是现在大多利用ES提供的Get或者Set函数代替computed。

import {Component} from 'vue-property-decorator';
@Component
export default class HelloDecorator extends Vue {
    count: number = 1

    // 获取计算属性
    get total(): number {
      return this.count + 1
    }

    // 设置计算属性
    set total(param:number): void {
      this.count = param
    }
}

2.4 @Component

Component装饰器它注明了此类为一个Vue组件,因此即使没有设置选项也不能省略。

import {Component} from 'vue-property-decorator';
@Component({
    components:{},
    computed:{},
    filters:{},
    ...
})  
export default class Two extends Vue{}

2.5 @Prop

Prop装饰器表明该组件可以接收其他组件的数据,如果该组件不用接收外部数据,则可以省略不写。

import {Component,Prop} from 'vue-property-decorator';
@Component
export default class Two extends 
Vue{
    @Prop(Number) propA!: number    //接收一个number类型的属性propA,该属性用以接收外部数据,该属性一定存在。
    @Prop({ default: 'default value' }) propB?: string    //接收一个string类型的属性propB,该属性的初始值是'default value',使用该组件时该属性不一定存在。
}

2.6 @Watch

watch装饰器是用来监控数据是否变化的。

<input :value="val"></input>
import {Component,Watch} from 'vue-property-decorator';

@Component
export default class Two extends 
Vue{
         val:boolean=true;
@Watch('val')
onValChange(val: boolean){
    this.$emit('update:date',date)    //当val发生变化时,则更新val。
    }
         
}

参考资料