typescript基础类型

基础类型

布尔型数字型字符串

1
2
3
4
5
6
7
8
9
// 布尔型
let boo: boolean = true;
bool = 111; // 报错

// 数字型
let num: number = 111;

// 字符串
let str: string = 'simplelife';

引用类型

Array类型Object类型Fcuntion类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 数组:两种定义方式 
let arr: Array<number> = [1,2,3,4]; // number 是数组元素的类型
let arr2: string[] = ['a','b']

// 函数类型 void
function func(arg: number): void {
// 限制参数是 number 类型
// 如果代码体内没有 `return` 返回值返回 void
}

// 函数必须返回 boolean 类型
function func2(): boolean {
// 必须返回布尔值类型值
return true
}

对象类型:更加复杂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 使用接口来定义对象的类型 interface
interface IPerson {
name: string;
age: number;
sex: string;
}
// obj对象继承 接口,必须有对应的属性,且类型要一直
let obj: IPerson = {
name: "simplelife",
age: 20,
sex: "男"
}
let obj2: IPerson = {} //空对象报错

// *******************************
// 可选项,允许为空
interface IPerson2 {
name?: string; // 表示字段允许没有
age?: number;
sex?: string;
}
let person12: IPerson2 = {} //不报错

// 定义任意类型的属性值,不确定属性类型
interface IPerson3 {
[propName: string] : any; // 可定义任意类型的
}

接口继承

1
2
3
4
5
6
7
8
9
10
11
12
// 继承关键字 extends
interface IA extends IPerson {
hobby:Array<string>;
}
let person2: IA = {
// 要写 IA新增的 和 IPerson自带的属性
}

// 继承多个接口
interface IB extends IA,IPerson2 {
// ………… IB具有 IA 和 IPerson2 的属性
}

特殊类型

Undefined类型Null类型

1
2
3
4
5
// undefined
let _undefined: undefined = undefined;

// null
let _null: null = null;

多重类型声明 或 |

1
2
let some_var: number | string | boolean = 123;
some_var = true // 正确

any 类型

不进行数据校验,等同于 js

与 &类型

1
2
3
4
// 继承了接口 IA 和 IB
let person3: IA & IB = {
// …………
}

接口实现 implements

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
interface IPerson4 {
name: string;
age: number;
sex: string;
getName (): string; // 两种写法
getAge: () => string;
}

class Person implements IPerson4 {
// 以上定义的类型,必须全写,不然会报错
// 实现接口
name: string = "simplelife";
age: number = 20;
sex: string; // 初始值可以不写
getName (): string {
return this.name;
};
getAge (): number {
return this.age;
};

// 写其它的不影响,类自己的方法
sayName (): void {

}
}

类型断言

1
2
3
4
5
6
7
8
9
10
11
function getLength (str: number | string): number {
if((str as string).length){
// 断言 str 是 string
return (str as string).length

// 第二中断言写法
return (<string>str).length
} else {
return str.toString().length
}
}

非空断言 !

1
2
3
4
function func3 (arg?: string): number {
return arg!.length //非空断言,等同于==> return arg && arg.length
}
func3() // 没有传参

枚举

1
2
3
4
5
6
7
enum Color {
red,
green,
yellow
}
console.log(Color,red) // 0 默认取索引值
console.log(Color,green) // 1 自增

反向映射

1
2
3
4
5
6
7
8
9
10
11
console.log(Color[0]) // red 通过反向映射得到属性值

// 如下,等同
{
red: 0,
green: 1,
yellow: 2,
0: 'red',
1: 'yellow',
2: 'green'
}

赋值枚举

1
2
3
4
5
6
7
8
9
10
11
12
// (1)
enum Color2 {
red = 1,
green, // 2,从red值自增
yellow // 3
}
// (2) 如果前一个枚举值是字符串,后一个必须赋值
enum Color2 {
red,
green = 'life',
yellow = 3 // 3
}

泛型

1
2
3
4
5
6
function func4<T>(arg: T): void {
}

// 根据实际情况,传入特定类型的值,为参数
func4<number>(44); // 必须传入数字类型
func4<string>('simple'); // 必须传入字符串类型

Vue组件写法

构建 vue + typescript 项目,在 src 会新增 shims-tsx.d.tsshims-vue.d.ts 文件,用于处理后缀名 .ts 文件,和 vue组件处理 ts 语法

vue组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// <script lang="ts"></script> 需要声明语言 ts
// 引入装饰器
import {Component,Vue} from 'vue-property-decorator';
/*
vue-property-decorator 装饰器列举
@Component
@Watch
@Prop
@Model ==> v-model
@Emit
*/
@Component({
name:'Home'
})
export default class Home extends Vue {
// 定义 data 数据
username: string = "simplelife";

// 定义 computed 方法
get fullName(){
return this.username
}
// set 方法
set fullName(val){
this.username = val;
}

// 定义 methods 方法
modifyName(){}
getName(){}
}

Watch侦听器

1
2
3
4
5
6
7
8
9
10
11
12
13
import {Component,Vue,Watch} from 'vue-property-decorator';
// 一下省略了重复代码,直接从侦听开始

// 定义一些数据
age: number = 18;
sex: string = "男";

@Watch('age')
changeAge(newValue,oldValue){
// 如果 age 发生改变了,会调用 changeAge 函数
}


Prop父子通信

父组件

通过 v-bind="item" 将该对象item的属性值,全都传入到子组件使用

1
2
3
4
5
<template>
<div>
<son v-for="item of userList" :key="item.id" v-bind="item"></son>
</div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import {Component,Vue} from 'vue-property-decorator';
// 导入子组件 Son
// 定义接口
interface IUser {
id: number;
name: string;
age: number;
sex?: number;
}

@Component({
name: "Father",
components:{
Son
}
})
export default class extends Vue {
userList: Array<IUser> = [
{
id: 1
name: "张三"
age: 20,
sex: 1
},
{
id: 1
name: "李四"
age: 18,
sex: 1
},
{
id: 1
name: "王五"
age: 21,
sex: 0
}
]
}

子组件 Son

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Compoment
export default class extends Vue {
@Prop(Number) // 之前js写法,传入的参数类型
id!: number; // 添加了非空断言,属性一定有

@Prop([String,Number]) //两种类型都可以
name!: string | number;

@Prop({type: Number}) //对象写法
age!: number;

@Prop({type: Number, default: 1}) //指定默认值
sex!: number;
}

Emit 绑定事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import {Component, Vue, Emit} from 'vue-property-decorator';

@Component
export default class extends Vue{
@Emit('on-remove')
remove(){
console.log('当触发`on-remove`事件,执行remove函数');
return value
}

// 如果不绑定事件名,默认就是下面的方法
@Emit()
deleteName(){
// 事件名会又小驼峰 ==> 横杠命名
}
}

组件绑定事件

1
2
3
4
5
6
7
// 在父组件中,使用子组件
<child @on-remove="fatherRemove"></child>

// fatherRemove 父组件方法,去触发事件
fatherRemove(val){
console.log(val)
}

Model 双向绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// html代码,接收firName
firName:<input type="text" :value="firName" @input="onChangeName">


// 省略部分代码
{
@Model('changeName',{type: String})
firName!: string;

@Emit('changeName')
onChangeName(e){
// 触发事件 changeName 并携带最新的 input value 值
return e.target.value
}

}

父组件

1
2
3
<template>
<child v-model="firName"></child>
</template>

生命周期函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import {Component,Vue} from 'vue-property-decorator';
@Component
export default class extends Vue {
// 钩子函数,正常写
beforeCreate(){}
created(){}

beforeMount(){}
mounted(){}

beforeUpdate(){}
updated(){}

beforeDestroy(){}
destoryed()
}

Vuex typescript 写法

./store/index.ts 模块集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import Vue from 'vue';
import Vux from 'vuex';

Vue.use(Vuex);
// 引入 IAboutState
import { IAboutState } from './module/about';

interface TRootState {
about: IAboutState; //引入模块
}
export default new Vuex.Store<TRootState>({
modules: {

}
})

./store/module/about.ts 一个模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import {Module, VuexModule, Mutataion, Action, getModule} from 'vuex-module-decorators';

import store from '../index.ts';// 去index.ts引入store
// 需要导出
export interface IAboutState{ //定义一个接口
count: number;
list: Array<number>;
}

@Module({
name: 'about',
dynamic: true, // 动态模块
store
})
export default class About extends VuexModule implements IAboutState {
// state 数据
count: number = 1;
list: Array<number> = [1,2,3,4];

// getter
get filterList () {
return this.number
}

// mutation
@Mutation
updateCount(payLoad: number){
this.count += payLoad;
}

// action
@Action
async getList (payLoad?: any){
const res = await getName();
}
}

// 通过 getModule
export const AboutStore = getModule(About)

组件使用

1
2
3
4
5
6
7
8
9
10
// 直接引入 AboutStore 能够使用里面的值
import { AboutStore } from "@/component/menu";
{
get count(){
return AboutStore.count //取出count值
}
get list(){
return AboutStore.filterList //取出count值
}
}