当前位置: 首页 > Web前端 > vue.js

走近Ts,用起来爽,用了之后一直爽(一)

时间:2023-03-31 20:50:54 vue.js

前言Vue3已经发布,ts的脚步再也不能停下来,只有es6?别想了,大家已经在行动了,下面就是ts的基础系列教程,ts的基础语法,高级语法等等,以及如何在vue项目中应用ts。跟着我开始吧。基本数据类型numberconsta:number=3;字符串常量b:字符串="1";arrayconstc:number[]=[1,2,3];constd:Array=[1,3];constarr:any[]=[1,"33",true];元组可以为数组conste中的每个参数定义对应的类型:[number,string]=[1,"ww"];enumerationenumerror{blue=3,"orange",}constf:error=error。橙色;console.log(f);//输出4tips如果最后一个未赋值的值是一个数字,那么这个未赋值的值就是前一个值+1的值。如果这个未赋值的前一个值没有被赋值,那么输出的就是它的下标。如果未赋值的前一个值不是数字,则必须赋值boolean类型constg:boolean=true;对象常量i:object={};undefined通常用于组合类型letj:number|不明确的;nulletk:null;void指定方法类型,表示没有返回值,返回函数aa()不允许在方法体中:void{console.log(1);}//如果方法有返回值,可以加上返回值函数的类型bb():number{return1;}never其他类型的子类型(包括null和undefined),表示从不出现值letl:never;//匿名函数并抛出异常l=(()=>{thrownewError("111");})();anytype让参数为任意类型leth:any=1;h=true;h="st";函数声明functioncc():void{}方法参数传递functiongetUserInfo(name:string,age?:number,school:string="TsinghuaUniversity"){return`name:${name}--age:${age}--school:${school}`;}tips:?表示可以传这个参数可以不传,不传就是undefined,也可以定义一个默认值。传递多个剩余参数时,如果使用剩余参数,可以将未定义的形参转化为数组函数sum(a:number,b:number,...arr:number[]):number{letsum:number=a+b;arr.forEach((元素)=>{sum+=元素;});控制台日志(arr);[3,4,5]返回总和;}console.log(总和(1,2,3,4,5));//15函数重载functionreload(name:string):string;functionreload(age:number):string;functionreload(param:any):any{returntypeofparam==="string"吗?`我是:${param}`:`我的年龄:${param}`;}console.log(reload(18));//时代提示:重载方法没有方法体,可以使用其中一种方法,根据参数的类型判断参数,但是如果传入的参数类型不是任何重载方法的参数类型,它将不允许通过。2个重载中的第一个“(name:string):string”出现以下错误。“never[]”类型的参数不可分配给“string”类型的参数。2个重载中的第2个“(age:number):string”出现以下错误。“never[]”类型的参数不能分配给“number”类型的参数类classPerson{//privatevariableprivatename:string;//构造函数constructor(name:string){this.name=name;}//获取名称getName():string{returnthis.name;}//设置名称setName(name:string):void{this.name=name;}}letp=newPerson("张三");p.setName("李四");控制台日志(p);inheritclassSonextendsPerson{//静态属性publicstaticage:number=18;//学校公立学校:字符串;//构造方法constructor(name:string,school:string){//在派生类的构造函数中访问“this”之前,必须调用“super”来初始化父类构造函数——并将参数传递给父类超(名字);//传入学校赋值给全局变量this.school=school;}//静态方法staticrun(name:string):string{return`${name}正在跑步,他的年龄只有${this.age}`;}}letson=newSon("王舞","清华大学");son.setName("赵六");//私有类不能在子类外访问,但可以赋值和访问在当前类、子类、类外可以访问protectedin在当前类和子类内部可以访问,类外不能访问。private在当前类内部是可以访问的,在子类或者类之外是无法访问的。不带修饰符的属性,默认是通过抽象方法/方法重载的公共(public)多态性--多态性--多态性用于定义标准//abstractparentclassabstractclassAnimal{privatename:string;构造函数(名称:字符串){this.name=name;}//抽象成员--methodabstracteat():any;//抽象成员——属性保护的抽象年龄:Number;睡眠():无效{控制台.log(“睡眠”);}}classcatextendsAnimal{ages:Number=2;构造函数(名称:字符串){超级(名称);}//非抽象类“cat”不会自动继承自“Animal”类的抽象成员“eat”必须在父类中手动定义抽象方法——多态eat():string{return"Thecat吃鱼”;}//多态sleep():string{return"ThecatisinSleep";}}console.log(newcat("33").sleep());tips:抽象类不能被实例化。非抽象类继承抽象父类时,不会自动实现父类的抽象成员。必须在父类中手动定义抽象成员,否则会报错。抽象成员包括属性和方法接口在面向对象程序设计中,接口是一种规范定义,它定义了行为和动作的规范。在编程中,接口起着约束和规范的作用。接口定义了某一批类需要遵守的规范。接口不关心这些类的内部状态数据,也不关心这些类中方法的实现细节。只是规定在这批类中必须提供某些方法。提供这些方法类即可满足实际需要。ts中的接口类似于java,同时增加了更灵活的接口类型,包括属性、函数、可索引和类等。第二个?:字符串;//加个问号,接口属性可以传也可以不传,不传默认是undefined。}//打印变量functionlogParam(name:InterfaceName):void{console.log(name.first,name.second,11);}//定义参数constobj={first:"1",second:"fff",三:1};//logParam({第一:"1",第二:"1",三:1});//报错,只能传接口定义的值logParam(obj);tips:使用一个变量来存储传入的变量,这样就可以传入定义接口以外的值,否则,如果直接传入对象中没有接口定义的值,会报错,所以建议传入哪些值是接口定义的。函数类型接口约束方法传入的参数类型和返回值类型,可以批量约束。interfacekeyMap{(key:string,value:string):string;}letlogKeyMap:keyMap=function(key1:string,value:string):string{returnkey1+value;};console.log(logKeyMap("key1","value"));tips:接口只对传入的参数类型和个数进行约束,不对参数名称进行约束。可索引接口约束数组接口Arr{[index:number]:string;}letss:Arr=["2121"];constraintobjectinterfaceObj{[index:string]:string;}letinterfaceArr:Obj={aa:"1"};tips:要约束数组,index后面必须跟数字类型。要约束对象,索引后面必须跟字符串类型索引签名参数类型必须是“string”或“number”类类型接口来约束类,类似于抽象类的实现。界面动物{名称:字符串;eat():void;}classDogsimplementsAnimals{name:string;构造函数(名称:字符串){this.name=name;}eat(){}}interfaceinheritance--interfaces可以被继承猫正在输入代码");}}//继承类后重新实现接口classSuperManextendsCatimplementsPersons{eat():void{console.log(1);}work():void{console.log(2);}}letsuperMan=newSuperMan();superMan.code();tips:类接口会约束类的属性和方法,类似于非抽象类继承抽象类时必须实现某些方法和属性,但是对属性和方法的类型的约束更严格,除了方法void类型可以重新定义之外,其他属性或方法的类型定义需要和接口保持一致。在通用软件工程中,我们不仅需要创建一致且定义明确的API,还需要考虑可重用性。组件不仅可以支持当前的数据类型,还可以支持未来的数据类型,这为您在创建大型系统时提供了非常灵活的功能泛型解决了类、接口、方法的可重用性,以及非特定数据类型的支持。要求:传入的参数和返回的参数与泛型函数getDate(value:T)一致:T{returnvalue;}console.log(getDate(123));tips:这里的T可以改成其他任意值,但定义的值与入参和返回参数相同。一般默认的写法是T,这也是业界的标准选择。类泛型类MinClass{公共列表:T[]=[];//添加add(value:T):void{this.list.push(value);}//找到最小值min():T{//假设这个值是最小的letminNum=this.list[0];for(leti=0;i();minClass.add(23);minClass.add(5);minClass.add(2);console.log(minClass.min());//实例化一个类,指定类的T的类型为string,则其方法的参数和返回为string类型letminClass2=newMinClass();minClass2.add("23");minClass2.add("5");minClass2.add("2");console.log(minClass2.min());接口第一种泛型写法interfaceConfigFn{//指定参数类型,返回值type(value:T):T;}letgetData:ConfigFn=function(value:T):T{returnvalue;};console.log(getData("z11"));第二种写法interfaceConfigFn{//参数类型,返回值类型(value:T):T;}//接口方法functiongetData(value:T):T{returnvalue;}//使用接口letmyGetDate:ConfigFn=getData;console.log(myGetDate("3"));tips:接口的泛型只针对函数类型的接口类as传入泛型类的参数//User类--与数据库表字段的映射classUser{username:string|不明确的;密码:字符串|不明确的;//构造函数-初始化参数constructor(param:{username:string|undefined;password?:string|undefined;}){this.username=param.username;this.password=param.password;}}//数据库类classDb{add(user:T):boolean{console.log(user);返回真;}updated(user:T,id:number):boolean{console.log(user,id);返回真;}}letu=newUser({username:"张三",});//u.username="李四";u.password="111111";letdb=newDb();db.add(u);db.updated(u,1);tips:类参数名和类型都有受限模块。内部模块称为命名空间,外部模块简称为模块。模块在自己的范围内执行,而不是在全局范围内执行;这意味着在模块等中定义的变量、函数和类在模块外部不可见,除非您使用其中一种导出形式显式导出它们。相反,如果要使用其他模块导出的变量、函数、类、接口等,则必须导入,可以使用其中一种导入形式。我们可以将一些常用的功能分离成一个文件,作为一个模块。模块中的变量、函数、类等默认都是私有的。如果我们要对外访问模块中的数据(变量、函数、类),就需要通过export暴露模块中的数据(变量、函数、类……)。暴露后,我们可以通过import引入模块来使用模块暴露的数据(变量,函数,类...)//modules/db.tsfunctiongetDate():any[]{console.log("获取数据");return[{userName:"张三",},{userName:"李四",},];}//一个模块可以多次使用//export{getDate};//一个模块只能使用一次导出默认getDate;从“./modules/db”导入{getDateasgetDbDate};从“./modules/db”导入getDbDate;getDbDate();tips:这个不能在浏览器调试的时候直接使用,可以在node和weakpack环境下调试使用。命名空间在代码量较大的情况下,为了避免各种变量、函数、类、接口等的名称发生冲突,可以将具有相似功能的放在命名空间中。TypeScript的命名空间可以将代码包裹起来,只对外暴露需要的部分。外部访问的对象。命名空间和模块的区别命名空间:模块内部,主要用来组织代码,避免命名冲突。Module:tsexternalmodule的缩写,注重代码复用,一个模块中可能有多个命名空间。//modules/Animal.tsexport命名空间A{interfaceAnimal{name:String;吃():无效;}exportclassDogimplementsAnimal{name:String;constructor(theName:string){this.name=theName;}eat(){console.log("我是"+this.name);}}}exportnamespaceB{interfaceAnimal{name:String;吃():无效;}exportclassDogimplementsAnimal{name:String;constructor(theName:string){this.name=theName;}eat(){}}}import{A,B}from"./modules/Animal";letee=newA.Dog("小北");ee.eat();Decorator类装饰器:类装饰器在类声明之前声明(靠近类声明),类装饰器应用于类构造函数,可用于监视、修改或替换类定义。函数logClass(参数:任何){console.log(参数);//params指的是当前类--HttpClientparams.prototype.apiUrl="动态扩展属性";params.prototype.run=function(){控制台。log("动态扩展方法");};params.prototype.getDate=function(){console.log("动态扩展方法二");};}@logClassclassHttpClient{constructor(){}getDate(){console.log(1);}}lethttp:any=newHttpClient();console.log(http.apiUrl);http.run();http.getDate();tips:装饰器会覆盖装饰类的方法。一个可以给装饰器工厂传递参数的装饰器console.log(param,"装饰器传递传入属性");};}@logClassB("Xiaohui")classHttpClients{constructor(){}getDate(){}}lethttps:any=newHttpClients();console.log(https);constructor装饰函数logClassC(target:any){console.log(target,1111);//这里用来继承目标类并重载方法和属性returnclassextendstarget{a:any="我是修改后的属性";getDate(){console.log(this.a+"--装饰器中方法的输出");}};}@logClassCclassHttpClient2{publica:string|不明确的;constructor(){this.a="我是构造函数中的a";}getDate(){console.log(this.a);}}consthttps2=newHttpClient2();https2.getDate();未完待续~下期预告:在vuets中使用。