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<number> = [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

组件声明
<script lang="ts">
  import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
  
  @Component
  export default class Test extends Vue {
    title: string;  // data
  }
</script>
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

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

推荐阅读更多精彩内容