一、介绍
官网:https://www.tslang.cn/
typescript是javascript超集,由微软开发并开源
它的语法规范、严谨,适合开发大型项目
二、环境搭建
1.安装
npm i typescript -g
验证是否安装成功
tsc -v
2.编译
(1)手动编译
创建一个后缀为ts的文件,比如index.ts,并编写js代码
tsc index.ts
只要执行了编译命令,就会创建一个同名的js出来
(2)自动编译
①创建一个项目,并用ts初始化
初始化好之后就在当前文件夹中存在一个tsconfig.json配置文件
tsc --init
②修改输出目录
"outDir": "./js"
③创建js目录,并在vscode菜单栏中找到终端 > 运行生成任务 > tsc监视
在ts文件中编写程序代码,就会自动的生成js文件
三、基本使用
1.声明变量和数据类型
ts最大的特点就是进行数据类型的验证,要求我们在声明一个变量的时候同时定义好该变量的数据类型。
(1)声明变量
语法格式:
var 变量名 : 数据类型名称 //声明变量并确定数据类型
var 变量名 : 数据类型名称 = 内容 //声明变量确定数据类型并直接赋值
示例代码:
var age : number;//声明一个age变量,并确定数据类型为number
age = 18 //这样进行赋值,没有问题
age = '18' //这样是给age变量赋值一个字符串18,这样就会提示类型不一致
(2)数据类型
string、number、boolean、function、object、array…
数组:
var 变量名 : Array<数组元素数据类型>
示例代码:
var users:Array<String>;
users = ['hello'];
ts新增数据类型
①元组
let 变量名 : [第一个元素的数据类型名称,第N个元素的数据类型名称]
示例代码:
let arr1 : [string,number,boolean];
arr1 = ['hello',2000,true]
元组的元素数据类型和预定义的数据类型一致才行
②枚举
enum 变量名 {值1,值N}
示例代码:
enum orderStatus { '已下单' = 1,'已发货','已收货' }
console.log(orderStatus.已收货)
③any
任意类型
var users2 : Array<any>;
users2 = [100,true,'hello'];
var str : any;//变量类型为any时,就可以给变量设置任何类型的数据
str = 100;str = true;str = ''
④void
函数返回值,表示此函数无返回值
⑤never
表示那些不存在的值的类型
function error(message:string) : never{
throw new Error(message);
}
2.函数
(1)定义
在ts中,定义一个函数,需要函数的返回值类型,如果没有返回值则类型就void,如果函数有参数的话,需要给参数指定数据类型。
语法格式:
function 函数名([参数名:参数数据类型]) : 返回值数据类型{...}
(2)函数的参数
①默认参数
function 函数名(参数名:参数类型 = 默认值) : 返回值数据类型{...}
②可选参数
function 函数名(参数名:参数类型,[参数名N?:数据类型]) : 返回值数据类型{...}
示例代码
function getUser(username:string,password?:string):void{
console.log(username)
console.log(password)//如果没有传递第二个参数,则是undefined
}
getUser('admin')
getUser('admin','admin123')
③剩余参数
function 函数名(参数名:参数类型,...参数名N:参数类型) : 返回值数据类型{...}
示例代码
function getStr(str1:string,...str2:Array<any>):void{
console.log(str1);
console.log(str2)
}
getStr('hello','ts','js','vue','react',100,true,{'user':'1111'})
调用函数时第一个参数正常传递和接收,其他参数都会被解析成第二个参数(数组类型)
3.接口
interface 声明接口
interface userinfo{
username:string,
age:number,
phone:number
}
var user1 : userinfo;
user1 = {
username:'小白',
age:18,
phone:12222222222
}
4.装饰器【重点】
装饰器是一个特殊的类型声明,它可以被附加到类、方法(函数)、属性、参数上面
可以修改类、方法、属性、参数的行为。它就是一个特殊的函数。
(1)类装饰器
①普通类装饰器
声明
function logClass(target:any):void{
//target 是调用装饰器的类
target.prototype.phone = 15511112222
}
调用
//调用装饰器
@logClass
class Person{
uname:string = '';
}
在声明类之前,用@装饰器名称来调用装饰器
②装饰器工厂
普通类装饰器无法传递参数,装饰器工厂可以接收参数,并返回一个装饰器,根据传递的参数就可以改变指定类的行为。
//装饰器工厂,可以接收参数
function logClass(params:any){
return function(target:any):void{
target.prototype.phone = params;
}
}
//调用装饰器并传递参数
@logClass(15612345678)
class Person{
uname:string = '';
}
(2)属性装饰器
声明装饰器
function logProperty(target:any,propertyName:any){
console.log(target,11111) //构造函数
console.log(propertyName,2222) //属性名称
}
调用装饰器
class Car{
@logProperty 声明属性之前调用装饰器
color : string = '';
}
var c1 = new Car();
(3)方法装饰器
运行时,可以接收三个参数
第一个参数是原型对象
第二个参数是方法的名称
第三个参数是方法的描述
function logAction(target:any,methodName:any,desc:any){
console.log(target,1111)
console.log(methodName,2222)
console.log(desc,3333)
}
class Car{
@logProperty
color : string = '';
@logAction //调用方法装饰器
drive():void{
console.log('drive....')
}
}
var c1 = new Car();
c1.drive();
(4)参数装饰器
运行时,可以接收三个参数
第一个参数是原型对象
第二个参数是方法的名称
第三个参数是参数的索引位置
class Car{
color : string = '';
drive(type:string="mini",@logParam speed:number = 100):void{
console.log(speed+'drive....')
}
}
var c1 = new Car();
c1.drive();
四、ts结合vue-cli脚手架使用
初始化项目
vue create ts-demo3
1.选择安装方式
? Please pick a preset:
Default ([Vue 2] babel, eslint)
Default (Vue 3 Preview) ([Vue 3] babel, eslint)
> Manually select features 选择自定义方式
2.选择使用的依赖,需要选择哪个就使用空格选中哪个,选择完成后回车
? Check the features needed for your project:
(*) Choose Vue version
(*) Babel
(*) TypeScript
( ) Progressive Web App (PWA) Support
(*) Router
(*) Vuex
( ) CSS Pre-processors
>( ) Linter / Formatter
( ) Unit Testing
( ) E2E Testing
3.选择vue版本,选择2.x,3.x选择是预览版
? Choose a version of Vue.js that you want to start the project with (Use arrow keys)
> 2.x
3.x (Preview)
4.是否使用类组件语法风格,选择y,回车
? Use class-style component syntax? (Y/n) y
5. 是否使用babel ,不使用 n
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (Y/n)
6.是否使用history模式
? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) n
7.配置文件存放方式,选择package.json
? Where do you prefer placing config for Babel, ESLint, etc.?
In dedicated config files
> In package.json
8.是否把以上配置保存作为以后项目默认配置?
? Save this as a preset for future projects? (y/N) n
1.定义类方式的组件
<script lang="ts">
import { Component,Vue } from 'vue-property-decorator'
// 定义类方式的组件
@Component({})
export default class Parent extends Vue{
}
</script>
2.新语法
(1)定义初始数据
<script lang="ts">
import { Component,Vue } from 'vue-property-decorator'
// 定义类方式的组件
@Component({})
export default class Parent extends Vue{
msg:string = ''//定义初始数据
}
(2)自定义函数
<template>
<div>
<h2>parent组件</h2>
<p>{{ msg }}</p>
</div>
</template>
<script lang="ts">
import { Component,Vue } from 'vue-property-decorator'
// 定义类方式的组件
@Component({})
export default class Parent extends Vue{
msg:string = ''//定义初始数据
changeMsg():void{
this.msg = '超级天王'//改变初始数据
}
//以函数名称的方式来使用生命周期钩子函数
mounted(){
this.changeMsg();
}
}
</script>
<style></style>
(3)计算属性
get 计算属性结果(){…}
//计算属性
get newNum():number{
return this.num + 30;
}
(4)组件通信
①父子组件
子组件通过@Prop装饰器来接收参数
第一步:创建两个页面组件,一个父组件,一个子组件
父组件:
<template>
<div>
<v-child :gift="msg"></v-child>
</div>
</template>
<script lang="ts">
import { Component,Vue } from 'vue-property-decorator'
import vChild from './child.vue'
// 定义类方式的组件
@Component({
components:{ vChild }
})
export default class Parent extends Vue{...}
子组件
<template>
<div>
<h3>这是child组件</h3>
<p>父组件传递的数据:{{ gift }}</p>
</div>
</template>
<script lang="ts">
import { Component,Vue,Prop } from 'vue-property-decorator'
@Component({})
export default class Child extends Vue{
@Prop({
type:String,
required:true
})
gift:string | undefined;
}
</script>
②子父组件
在父组件中使用子组件,并传递自定义事件,然后在子组件中通过Emit装饰器来触发父组件的事件
父组件:
<template>
<div>
<p>{{ newNum }}</p>
<v-child :gift="msg" @changeNum="changeNum"></v-child>
</div>
</template>
<script lang="ts">
import { Component,Vue } from 'vue-property-decorator'
import vChild from './child.vue'
// 定义类方式的组件
@Component({
components:{ vChild }
})
export default class Parent extends Vue{
num:number = 10;
changeNum(n:number){
this.num = n;
}
}
</script>
子组件
<template>
<div>
<button @click="send">发生数据给父组件</button>
</div>
</template>
<script lang="ts">
import { Component,Vue,Prop,Emit } from 'vue-property-decorator'
@Component({})
export default class Child extends Vue{
@Emit('changeNum')//触发父组件传递的事件
send():number{
return 20;//传递参数给父组件
}
}
</script>