Typescript的学习
1:什么是Typescript
1)Typescript不是新的语言,是JavaScript语言的超集
2)Typescript是由微软开发的开源编程语言,增加了非常有用的编译时类型检查特性*,最终被编译成JavaScript来执行
2:为什么要学习Typescript
- 提升自身技能
2)增加了代码的可读性和可维护性,开发大型项目
3)如果不显示定义类型,能够自动做出类型推论
4)Typescript拥有活跃的社区
缺点:增加学习成本 增加了设定类型的开发时间
3:如何去使用Typescript
ts的学习,学习的是语法,好多的语法,es5,es6…已经学过了
-
ts文件可以直接引入的
<script src="index.ts" ></script>
-
环境安装
ts的很多语法浏览器是不支持,安装环境,将ts进行编译,编译成浏览器可以执行的js
安装·
npm install -g typescript
检测是否安装成功
tsc -v //可以查看到版本说明安装成功
-
编译文件
tsc xxx.ts //同级目录下生成一个同名的js文件 tsc --outDir ./js xxx.ts //把ts文件编译到指定的目录
-
自动编译 tsconfig.json
ts --init //生成tsconfig.json配置文件
“outDir”:‘出口文件名’ 出口文件设置
“rootDir”:“入口文件名” 入口文件设置修改tsconfig.json,配合tsc -w 实时热更新
4:Typescript类型介绍
ts类型是非常严格的,定义了什么类型就必须是什么类型
let b=10; //正确 规定b是数值类型
b="123" //Type '"123"' is not assignable to type 'number'.2 b="123"
- 声明变量
语法:
let 变量名:数据类型; //声明变量并指定数据类型,给变量赋值必须是指定的该数据类型
let 变量名:数据类型= 值;
代码:
let num:number;
num=58;
// num="str" 错误的
let n:number=45;
console.log(n)
在typescript中给我们提供了以下数据类型
- 字符串(string)
- 数字类型(number)
- 布尔类型(boolean)
/**
* 字符串
*/
let str:string;
str="123"
let str1:string="78";
/**
* number 数值
*/
let n:number;
n=12;
let n2:number=23;
console.log(n2)
/**
* 布尔 boolean
*/
let bool:boolean;
bool=true;
-
null和undefined
/* null和undefined是所有类型的子类型 undefined表示未定义的值 null代表空 一个对象被人为的定义为空对象 */ let tmp:undefined; tmp=undefined; // let tmp1:number=undefined; //错误的 let tmp2:null=null; // tmp2={} 报错
-
数组类型(array)
/**
*数组
const arr=[1,"25",true]
const arr1=new Array()
*/
// ts中有两种方式定义数组 ---数组中每一个数据的元素类型指定什么类型就只能是什么类型
// 1--在元素类型后面加上[]--
const arr:string[]=["1","5"];
// arr[0]="45";
// arr[1]='true';
// console.log(arr)
// 2---使用数组泛型 Array<元素类型>
const arr1:Array<number>=[25,36];
let arr2:Array<boolean>;
arr2=[true,false]
-
any类型
/** * any任意类型 可以是任何数据类型 */ let a:any; a=5; a="123"; a=true; const arr5:any[]=[45,"bugai",true]; const arr6:Array<any>=[45,"123"] console.log(arr5,arr6)
-
元组类型(tuple)
/** * 元组类型 表示一个已知元素数量和类型的数组,各元素的类型不必相同 * * 语法:const 变量名:[类型1,类型2,类型3]=[14,"1ew",true] * 注意:前面有几个类型 后面就只能有几个值 * 每一对类型和值必须一一对应 */ // let arr7:[string,boolean,number,string]=[];//错误[]没有值,数量不统一 let arr7:[string,boolean,number,string]=["hello",true,25,"58"];
-
枚举类型(enum)
/** * 枚举类型 * 我们的值只会出现在一定范围中 * 性别: 男 女 保密 * 状态: 成功 失败 * 请求方式 : get,post,delete... * * 语法: * enum 枚举名 {标记名1,标记名2,标记名3} * 默认 0 1 2 * enum 枚举名 {标记名1=值,标记名2=值,标记名3=值} * * 使用 * let 变量:枚举名=枚举名.标记名 * */ enum Sex {man,women} let s:Sex=Sex.women console.log(s) enum Status {success=200,err=400} let result:Status=Status.success console.log(result)
-
void类型
/** * * void 没有任何类型 主要指的是函数没有返回值 */ function fn():void{ console.log(1) } fn()
-
never类型
/** * never 类型 异常 */ function fn2(): never { throw new Error() }
-
类型断言
/** * 类型断言:告诉编译器你比它更了解这个类型,并且它不应该发出错误,就是告诉不要去 * 对这个值进行类型检查 * */ function fn3(x:any):any{ if(typeof x==='string'){ // return (<string>x).length return (x as string).length } }
5:ts中函数定义
1:为函数定义类型
/****为函数定义类型
* 1:参数类型定义
* 2:返回值类型定义
* 第一种:
* function 函数名(参数:数据类型):返回值数据类型{
* return 值; //值的类型必须和返回值的数据类型一致
* }
* 第二种:
* let 函数名=function(参数:数据类型):返回值数据类型{
*
* }
* void 函数没有返回值
*/
function show(num:number):void{
console.log(num)
}
show(24)
function show1(x:string,y:string):string{
return x+y;
}
console.log(show1("中公","优就业"))
let show2=function (x:number,y:string):void{
console.log(x+y)
}
show2(14,"it")
let show3=function():string{
return "web前端"
}
console.log(show3())
可选参数
/**可选参数
* js中参数是可选的 不传时候值为undefined
* ts 可选参数使用 ? 定义
* 注意:ts中没有配置可选参数,你不传值 就会报错
*/
function get(x:string,y?:number):string{
return x+y;
}
console.log(get("中公",520))
console.log(get("中公"))
默认参数
/******默认参数 末尾的参数才能设置默认参数 */
function getd(x:number,y:number=25):number{
return x+y;
}
console.log(getd(12,23))
console.log(getd(12))
剩余参数
/****剩余参数
*
* 你想同时操作多个参数,或者你并不知道会有多少参数传递进来
*/
function get1(...data:any[]){
console.log(data)
}
// get1(1,2,3,true)
// get1(1)
// 剩余参数要放在尾部
function get2(x:number,...data:any[]){
console.log(data)
}
get2(25,"123","aaa","bbb")
6:ts装饰器
装饰器是对类,函数,属性的一种装饰,可以针对其添加一些额外的行为
通俗点理解就是在原有代码的外层包装了一层处理器
装饰器其实就是一个函数
启用装饰器特性,需要在tsconfig.json
里启用experimentalDecorators
编译器选项
"experimentalDecorators": true,
装饰器就是在调用某个方法,某个属性,某个类,某个参数之前执行一段函数,
定义装饰器
function 装饰器名(target){
} //不能传参数
function 装饰器名(参数:类型){
return function(target){
}
}
类装饰器
function 装饰器名(target){
}
@装饰器名
class 类名{
} //该类被实例化的时候装饰器函数就会被调用
代码
function add(target:any){
console.log(target,"target")
target.prototype.num=12;
}
@add //后面不能加任何符号
class Stu{
constructor(){
console.log("构造函数")
}
}
let s1=new Stu()
console.log(s1)
可以传参的装饰器
function add(num:number){
return function(target:any){ //return 的函数才是真正的装饰器
console.log(target,"target")
}
}
@add(15) //后面不能加任何符号
class Stu{
constructor(){
console.log("构造函数")
}
}
let s1=new Stu()
console.log(s1)
方法装饰器
function 装饰器名(类的原型对象,方法名,方法属性描述){
}
class 类名{
@装饰器名
方法名(){
}
}
function add(target:any,name:any,desc:any){
console.log(target,"target")
console.log(name,"方法名")
console.log(desc,"属性描述")
}
class Stu{
@add //后面不能加任何符号
run(){
console.log("nihao")
}
}
let s1=new Stu()
console.log(s1)
属性装饰器
function 装饰器名(类的原型对象,属性名){
}
class 类名{
@装饰器名
public 属性名
}
function add(target:any,propertyKey:any){
console.log(target,"target")
console.log(propertyKey)
}
class Stu{
@add //后面不能加任何符号
public name:string;
constructor(n:string){
this.name=n;
}
}
let s1=new Stu("zhans")
console.log(s1)
参数装饰器
function required(target:any, propertyKey: string, parameterIndex: number){
console.log(target) //类的原型对象
console.log(propertyKey) //方法名
console.log(parameterIndex) //参数的索引位置
}
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet(@required name: string) {
return "Hello " + name + ", " + this.greeting;
}
}
7:vue-cli脚手架升级
1:如果安装旧版本 卸载
npm uninstall vue-cli -g
安装
npm install @vue/cli -g
查看版本
vue -V
or
vue --version
2:初始化项目
vue create 项目名
启动项目
yarn serve
3:目录结构对比
4:使用ts语法开发
vue-property-decorator 是vue社区提出的一个对vue使用class类方式开发的一个重要包
1:创建组件About.vue
<template>
<div>
about
</div>
</template>
<script lang="ts">
// lang="ts"表示使用ts语法
// 引入类装饰器
import {Component ,Vue} from 'vue-property-decorator'
@Component({})
// 使用class方式创建类
export default class About extends Vue{
}
</script>
<style lang="stylus">
</style>
2:引入组件
<template>
<div id="app">
<!-- 3---调用组件 -->
<About></About>
</div>
</template>
<script lang="ts">
import {Component ,Vue} from 'vue-property-decorator'
// 1--引入组件
import About from './components/About.vue'
// 2---使用引入的组件
@Component({
components:{
About
}
})
export default class App extends Vue{
}
</script>
<style lang="stylus">
</style>
3:新语法–定义data数据
<template>
<div>
about
{{str}}
<li v-for="(item,index) in arr" :key="index">
{{item}}
</li>
</div>
</template>
<script lang="ts">
// lang="ts"表示使用ts语法
// 引入类装饰器
import {Component ,Vue} from 'vue-property-decorator'
@Component({})
// 使用class方式创建类
export default class About extends Vue{
str:string="中公it优就业" //没有data 直接定义
private arr:any[]=["aaa","Bbb","cccc"];
}
</script>
4:新语法—生命周期
<script lang="ts">
// lang="ts"表示使用ts语法
// 引入类装饰器
import {Component ,Vue} from 'vue-property-decorator'
@Component({})
// 使用class方式创建类
export default class About extends Vue{
str:string="中公it优就业" //没有data 直接定义
private arr:any[]=["aaa","Bbb","cccc"];
created(){
console.log("生命周期created")
}
mounted(){
console.log("mounted")
}
}
</script>
新语法–没有了methods
<template>
<div>
<li v-for="(item,index) in arr" :key="index">
{{item}} <button @click="del(index)">删除</button>
</li>
<button @click="changestr">修改str</button>
</div>
</template>
<script lang="ts">
// lang="ts"表示使用ts语法
// 引入类装饰器
import {Component ,Vue} from 'vue-property-decorator'
@Component({})
// 使用class方式创建类
export default class About extends Vue{
str:string="中公it优就业" //没有data 直接定义
private arr:any[]=["aaa","Bbb","cccc"];
changestr(){//修改str
this.str="北京中公教育科技有限公司"
}
del(index){
this.arr.splice(index,1)
}
}
</script>
新语法—没有了computed 直接写前面带上get
<template>
<div>
about
{{str}}
<li v-for="(item,index) in arr" :key="index">
{{item}} <button @click="del(index)">删除</button>
</li>
{{mystr}}
<button @click="changestr">修改str</button>
</div>
</template>
<script lang="ts">
// lang="ts"表示使用ts语法
// 引入类装饰器
import {Component ,Vue} from 'vue-property-decorator'
@Component({})
// 使用class方式创建类
export default class About extends Vue{
str:string="中公it优就业" //没有data 直接定义
private arr:any[]=["aaa","Bbb","cccc"];
created(){
console.log("生命周期created")
}
mounted(){
console.log("mounted")
}
changestr(){//修改str
this.str="北京中公教育科技有限公司"
}
del(index){
this.arr.splice(index,1)
}
get mystr(){
return "我的公司是"+this.str
}
}
</script>
新语法 没有watch 在前面加上watch装饰器
// 监听
// 浅监听 @Watch('监听的变量')
@Watch('str')
changefn(newval:string,oldval:string){
console.log("新值是"+newval,"旧值是"+oldval)
}
// 深度监听
// @Watch(监听的变量,{immediate:true,deep:true})
@Watch('arr',{immediate:true,deep:true})
changearr(newval:any){
console.log("新值为",newval)
}
组件通信------父传子
父组件
<template>
<div id="app">
<!-- 3---调用组件 -->
<About :message="message"></About>
</div>
</template>
<script lang="ts">
import {Component ,Vue} from 'vue-property-decorator'
// 1--引入组件
import About from './components/About.vue'
// 2---使用引入的组件
@Component({
components:{
About
}
})
export default class App extends Vue{
message:string="欢迎来到中公教育"
num:number=25;
}
</script>
子组件
<template>
<div>
{{message}}
</div>
</template>
<script lang="ts">
// lang="ts"表示使用ts语法
// 引入类装饰器
import {Component ,Vue, Watch,Prop} from 'vue-property-decorator'
@Component({})
// 使用class方式创建类
export default class About extends Vue{
// @Prop 属性装饰器
// @Prop(String) readonly message:string |undefined
// 1:传入message属性,只读,是string类型,可以传入可以不传入
// @Prop([String,Number]) readonly message?:string |number
// 2: 传入message属性,只读 可以是number或string ?表示不传入 !表示必须传入
@Prop({
type:String, //多个就写[Number,String]
default:"hellow",
required:true,
validator:function(val){
return val.length>3;
}
})
private message:string|undefined
}
</script>
<style lang="stylus">
</style>
组件通信 子传父
@Emit装饰器
父组件
<template>
<div id="app">
{{message}}
<!-- 3---调用组件 -->
<About @to-parent-fn="changefn"></About>
</div>
</template>
<script lang="ts">
import {Component ,Vue} from 'vue-property-decorator'
// 1--引入组件
import About from './components/About.vue'
// 2---使用引入的组件
@Component({
components:{
About
}
})
export default class App extends Vue{
message:string="欢迎来到中公教育"
num:number=25;
changefn(val:string){
this.message=val
}
}
</script>
<style lang="stylus">
</style>
子组件
<template>
<div>
<!-- 直接调用@Emit -->
<!-- <button @click="toParentFn">传值1</button> -->
<button @click="go">传值1</button>
</div>
</template>
<script lang="ts">
// lang="ts"表示使用ts语法
// 引入类装饰器
import {Component ,Vue, Watch,Emit} from 'vue-property-decorator'
@Component({})
// 使用class方式创建类
export default class About extends Vue{
private msg="我是中公讲师"
// 1---不传入事件名,表示下面紧贴的函数就是自定义事件
// @Emit()
// toParentFn(){
// return this.msg; //return 的值就是传递给父组件的值
// }
// 2 传入事件名,事件名就是该自定义事件
// @Emit('to-parent-fn')
// toParentFn(){
// return this.msg+"2222"
// }
// 3--跟方法1 相同 只不过间接调用
@Emit()
toParentFn(){
return this.msg+"33333"
}
go(){
this.toParentFn()
}
}
</script>
<style lang="stylus">
</style>
配置文件
手动在根目录下创建vue.config.js文件
module.exports={
devServer:{
proxy:{
'/api':{
target:'http://xxx.com',
ws:true,
changeOrigin:true
}
}
}
}
重新启动项目
错误集锦
‘n’ was also declared here.
n被使用过了