TypeScript在Vue中的使用

基础

1,类型
// 布尔值
let isDone: boolean = false;

// 定义变量之后,不可随便改变它的类型
isDone = true; // 不报错
isDone = '赋值字符串'; // 报错

// 字符串
let name: string = 'bob';
// 数字
let age: number = 18;

// 数组
let list1: number[] = [1, 2, 3]; // 在类型后面直接加[],表示由此类型元素组成的一个数组
let list2: Array = [1, 2, 3]; // 使用数组泛型,Array<元素类型>

// 类型的或
let str: number | string = 'a';
str = 1; // 不报错

// any
let anyVar: any = 'any';
anyVar = [1, 2, 3]; // 不报错

// void
function func(params: string): void {
  ...
}

除了上面的常见的基本类型意外,还可以通过接口(interface)定义对象类型

// 对象,使用接口(interface)来定义对象类型
interface Student {
  name: string;
  age: number;
}
let studentA: Student = {
  name: '啊A',
  age: 25,
}
// 报错,对象必须有name和age属性
let studentB: Student = {}

// 将这两个属性改成可选项,问号表示可选项
interface Student2 {
  name?: string;
  age?: number;
}

// 不报错
let studentC: Student2 = {}
// 额外属性
interface Student3 {
  name?: string;
  age?: number;
  [propName: string]: any; // 额外属性
}

// 报错,因为Student2类型没有english属性
let studentD: Student2 = {
  name: '啊D',
  age: 10,
  english: 90,
}
// 不报错
let studentD: Student3 = {
  name: '啊D',
  age: 10,
  english: 90,
}

// 接口的继承
interface Student4 extends Student {
  hobby: string[];
}
2,枚举

使用枚举可以避免写一些魔鬼数字和更清晰的表达一些常量的意义。

// 数字枚举,如下,Up使用初始化为 1。 其余的成员会从 1开始自动增长。
// 如果没有初始化的话,自然Up的值为0
enum Direction {
  Up = 1,
  Down,
  Left,
  Right
}

// 字符串枚举
enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT",
}
3,高级类型
交叉类型

交叉类型是将多个类型合并为一个类型。形成一个拥有这几个类型所有成员的新类型。

interface A {
  name: string,
  age: number
}
interface B {
  enName: string,
  age: number
}

let a: A & B;

// 都是合法的
a.age
a.name
a.enName
联合类型

可以使类型具有一定的不确定性,可以增加代码的灵活性

interface A {
  name: string,
  age: number
}
interface B {
  enName: string,
  age: number
}

let a: A | B

//  Property enName does not exist on type A | B. Property enName does not exist on type A.
a.enName

// 合法
a.age

使用

在 vue 中使用 typescript 非常好用的几个库

  • vue-property-decorator: vue-property-decorator是基于 vue-class-component 所做的拓展。
  • vuex-module-decorators: 用 typescript 写 vuex 很好用的一个库。
vue-property-decorator

安装 npm install --save vue-property-decorator

  • @Component
  • @Prop
  • @Watch
  • @Emit
  • @Model
  • @Inject
  • @Provide
  • @Component (provided by vue-class-component)
  • Mixins (the helper function named mixins provided by vue-class-component)
组件声明

Prop 声明
// JS写法
props:{
  propA: String,
  propB: [String, Number],
  propC: {
    type: Array,
    default: 'this is default value',
    required: true
  }
}
// TS写法
@Prop(String) propA: string;
@Prop([String, Number]) propB: string | number;
@Prop({type: string, default: 'this is default value', required: true})propC: string;

@Prop(options: (PropOptions | Constructor[] | Constructor) = {})

  • PropOptions: Prop的type,default,required,validator等配置
  • Constructor[]: 指定Prop的任选类型
  • Constructor: 如String,Number,Boolean等,指定Prop类型
method
// JS写法
sayHi(name) {
  console.log(`Hi~! I am ${name}`)
}
// TS写法,与JS写法基本一致,入参需添加参数类型,方法名后面添加方法返回值。
sayHi(name: string): void {
  console.log(`Hi~! I am ${name}`)
}
computed 计算属性
// JS写法
computed: {
  myName() {
    return `I am xxx`;
  } 
}
// TS 写法,直接用get
get myName(): string {
  return `I am xxx`;
}
Watch 监听属性
// JS写法
watch: {
  student: {
    handler (newVal) {
      console.log(`student:  new valule is ${newVal}`);
    },
    deep: true,
    immediate: true
  }
}
// TS 写法
@Watch('student', {deep: true, immediate: true})
studentChange(newVal) {
  console.log(`student:  new valule is ${newVal}`);
}

@Watch(path: string, options: WatchOptions = {})

  • path: 监听的变量
  • WatchOptions: 包含两个属性 immediate?:boolean 侦听开始之后是否立即调用该回调函数 ; deep?:boolean 被侦听的对象的属性被改变时,是否调用该回调函数
Emit 事件
count = 0
// JS 写法
addToCount(n) {
  this.count += n
  this.$emit('add-to-count', n)
}
// TS写法
@Emit()
addToCount(n: number) {
  this.count += n
}

// JS写法
resetCount() {
  this.count = 0
  this.$emit('reset')
}
// TS写法
@Emit('reset')
resetCount() {
  this.count = 0
}

// JS写法
returnValue() {
  this.$emit('return-value', 10)
}
// TS写法
@Emit()
returnValue() {
  return 10
}

// JS写法
onInputChange(e) {
  this.$emit('on-input-change', e.target.value, e)
}
// TS写法
@Emit()
onInputChange(e) {
  return e.target.value
}

// JS写法
promise() {
  const promise = new Promise(resolve => {
    setTimeout(() => {
      resolve(20)
    }, 0)
  })
  promise.then(value => {
    this.$emit('promise', value)
  })
}
// TS写法
@Emit()
promise() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(20)
    }, 0)
  })
}

@Emit(event?: string)

  • @Emit 装饰器接收一个可选参数,该参数作为$emit的第一个参数,充当事件名。如果没有通过参数提供事件名,则会将函数名的 camelCase 转为 kebab-case。
  • @Emit 会将回调函数的返回值作为第二个参数。如果返回值是一个 Promise 对象,$emit 会在 Promise 对象被标记为 resolved 之后触发。
  • @Emit 的回调函数的参数,会放在其返回值之后,一起被$emit 当做参数使用。
vuex-module-decorators

安装 npm install -D vuex-module-decorators

import { VuexModule, Module, Mutation, getModule, Action } from 'vuex-module-decorators';
import Vuex from 'vuex';

const store = new Vuex.Store({});

@Module({ dynamic: true, store, name: 'demo' })
class Demo extends VuexModule  {
  name: string = '';

  @Mutation
  setName(data) {
    this.name = data;
  }
  
  @Action({ commit: 'setName' })
  async getName() {
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve('this is Name')
      }, 3000)
    })
  }
}

export const DemoModule = getModule(Demo);

参考内容

https://www.w3cschool.cn/typescript/typescript-tutorial.html
https://www.typescriptlang.org/
https://github.com/kaorun343/vue-property-decorator
https://www.npmjs.com/package/vue-property-decorator

你可能感兴趣的:(TypeScript在Vue中的使用)