Vue3+TSt初学

一、TS初识
//TS文件代码
(()=>{
    function printStr(str:string){
        return '你好'+str;
    }
    let str = 'learn cool';
    console.log(printStr(str));
})

//1、将ts文件通过在HTML文件中通过script标签引入
//2、通过tsc tab键编译ts文件 生成的js文件
//编译后的JS文件代码
(function () {
    function printStr(str) {
        return '你好' + str;
    }
    var str = 'learn cool';
    console.log(printStr(str));
});

ts文件编译成js代码的区别

  • 1、ts文件中可以写js的代码
  • 2、ts中的类型定义在编译成js后消失
  • 3、ts变量中使用let 定义,编译成js文件后变成var声明;
1.1vscode 可以自动编译ts代码
//1、执行tsc --init生成tsconfig.json
//2、修改config 文件outDir为./js
//3、打开终端、运行所有任务,监视ts
//4、创建ts文件自动生成js,创建html文件引入js文件,写ts代码
二、类型注解(约束函数、变量的)

类型注解:是一种轻量级的为函数或者变量添加的约束

  • 如果定义的是什么类型 那么传入的参数就必须是什么类型;
(()=>{
    function showMsg(str:String){
        return str+'nihao'
    }
    // let str = 'xiao';
    // console.log(showMsg(str));
    let str = [1,2,3,4,5];
    console.log(showMsg(str));
    //1、首先当定义的参数类型为什么的时候就必须传入什么类型的参数,否则报错
    console.log(showMsg());
    //2、其次当定义时有参数传入时 就必须传入参数,否则会报错
    //3、这两种情况在js文件中并不会报错,是因为js属于弱类型语言
})()

在这里插入图片描述

三、接口

1、接口:是一种能力一种约束而已;
2、ts文件中会实时对代码进行语法分析,即使告诉我们语法是否有误

// 接口:是一种能力一种约束而已
(()=>{
    interface Iperson {
        firstName:String,
        lastName:String
    }

    function showFullName(person:Iperson){
        return person.firstName +'_'+ person.lastName
    }

    // 定义一个person 变量
    let person = {
        firstName:'东方',
        lastName:'不败'
    }

    console.log(showFullName(person));
})()
四、类
(()=>{
    interface Iperson{
        firstName:String,
        lastName:String
    }

    //定义一个类
    class Person{
        firstName:string
        lastName:string
        fullName:string
        //定义一个构造函数
        constructor(firstName:string,lastName:string){
            // 更新属性数据
            this.firstName = firstName;
            this.lastName = lastName;
            this.fullName = this.firstName+"_"+this.lastName
        }
    }

    // 定义个函数
    function showFullName(person:Iperson){
        return person.firstName+"-"+person.lastName;
    }

    // 通过类实例化一个对象 传进去的是一个对象
    let person = new Person('诸葛','孔明')

    console.log(showFullName(person));
})()
五、使用webpack打包TS

参考文档

六、TS语法的学习
6.1基本数据类型
  • ts与js类似,无非就是在变量名后面加上了数据类型;
let str:string = '小明';
let num:number = 1000;
let flag:boolean = true;

总结:ts中变量一开始是什么类型,那么后期赋值的时候也只能用这个类型的数据,是不允许用其他类型的数据赋值给当前的这个变量的;如:let str:string = ‘真香’ str = 50,没有武德(不允许)

在这里插入图片描述

//布尔类型
    let flag:boolean = true;
    // flag = 10;
    console.log(flag);

    //数字类型
    let num:number = 10;
    // num = '哈哈'
    console.log(num)

    //字符类型
    let str1:string = '床前明月光';
    let str2:string = '疑似地上霜';
    let str3:string = '举头望明月';
    let str4:string = '低头思故乡';

    let str = `${str1},${str2},${str3},${str4}`;
    console.log(str)

    //字符数字组合
    let num1:number = 1000;
    let str5:string = '我现在有多少万元';
    let res = str5+num1;
    console.log(res)


    //null、undefined
    let und:undefined = undefined;
    let nul:null = null;
    console.log(und,nul);
    //undefined和null都可以作为其他类型的子类型,把undefined和null赋值给其他类型的变量,如number类型的变量
    let num6:number = undefined;
    let num7:number = null;
    console.log(num6,num7);

    //1、数组类型
    //1.1数组的定义
    let arr1:number[] = [1,2,3,4,12];
    console.log(arr1);
    //1.2泛型的定义
    let arr2:Array<number>=[100,20,30]
    console.log(arr2);

    //元祖类型
    let arr3:[string,number,boolean] = ['小明',100.124,true];
    console.log(arr3[0].split(''))
    console.log(arr3[1].toFixed(2))


    console.log('=======enum 枚举');
    enum Color{
        red=1,
        green,
        blue
    }
    let color:Color=Color.red;
    console.log(color);
    //根据编号可以查到对应的值,根据值能获取对应的编号,默认从0开始,依次递增1;
    console.log(Color.red,Color.green,Color.blue);
    //可以给枚举中的值赋予编号
   console.log(Color[3]);




   console.log('any类型========');

   let str8:any = 1000;
   str8 = '黎明';
    //优点:
   let arr4:any[]=[100,'xiao',true,100.2];
    //缺点:不会出现错误,编译可通过,但是结果错误
    // console.log(arr4[0].split(''))


    console.log('void=====没有任何类型')

    function showMsg():void{
        console.log('xiaoming')
    }

    showMsg();//xiaoming
    console.log(showMsg())//没有返回值 undefined

    console.log('Object类型=======')
    // 定义一个函数,参数是Object类型,返回值也是Object类型
    function getObj(obj:Object):Object{
        console.log(obj);
        return{
            name:'小明',
            age:13
        }
    }
    console.log(getObj({name:'12312'}));

    console.log('联合类型==========')
    function getStr(str:string|number):string{
        return str.toString();
    }

    getStr('123');//'123'
    getStr(123);//'123'



    console.log('类型断言=======');
    // 需求1:定义一个函数获取函数或者字符的长度
    function getLength(obj:string|number):number{
        if((<string>str).length){
            // return str.length;
            return (str as string).length
        }else{
            return str.toString().length;
        }
    }

    console.log('类型推断======')
    let numb = 100;

    let name;
7、接口
// id是number类型, 必须有, 只读的
// name是string类型, 必须有
// age是number类型, 必须有
// sex是string类型, 可以没有

//定义一个接口,该接口作为person对象的类型使用,限定或者是约束该对象中的属性数据
interface Iperson{
    //定义id为只读类型 readonly 不可改变
    readonly id:number
    name:string
    age:number
    //sex可有可无 用?
    sex?:string
}

//定义一个对象。该对象的类型就是我定义的Iperson
const person:Iperson={
    id:1,
    name:'gtt',
    age:13,
    //需求中sex属性可有可无
    sex:'女'
}
8、函数类型
 console.log('函数类型')
// 函数类型:通过接口的方式作为函数的类型来使用

// 为了使用接口表示函数类型,我们需要给接口定义一个调用签名。
// 它就像是一个只有参数列表和返回值类型的函数定义。
// 参数列表里的每个参数都需要名字和类型

// 函数类型:通过接口的方式,作为函数的类型来使用

// 定义一个接口,用来作为某个函数的类型使用
// 需求:在第一个参数中找第二个参数是否存在其中,返回布尔类型
interface Isearch{
    // 定义一个调用签名
    (source:string,subStr:string):boolean
}


let searchStr:Isearch = function (source:string,subStr:string):boolean{
    return source.search(subStr)>-1
}

console.log(searchStr('haha,小明','明'));//true
9、类类型(类的类型通过接口来实现)
console.log('类');

// 1、定义一个接口
interface IFly{
    // 该方法中没有任何的实现(方法中什么都没有)
    fly()
}

// 2、定义一个类,这个类的类型就是上面定义的接口(实际上也可以理解为IFly接口约束了当前的这个Person类)
class Person implements IFly{
    // 实现接口中的方法
    fly() {
        console.log('会飞')
    }
}

let person1 = new Person();
person1.fly();//会飞

// 3、定义另一个接口
interface ISwim{
    swim()
}

// 定义一个类这个类的类型就是IFly,ISwim
//当前这个类可以实现多个接口,一个类可以被多个接口约束
//通俗理解为 一个人可以拥有多个能力
class Person2 implements IFly,ISwim{
    fly(){
        console.log('fly2')
    }
    swim() {
        console.log('游泳2')
    }
}

let person2 = new Person2();
person2.fly();//fly2
person2.swim();//游泳2


//为了避免接口数量过多 我们可以使用接口继承接口
interface FlyandSwim extends IFly,ISwim{};

class Person3 implements FlyandSwim{
    fly(){
        console.log('fly3')
    }
    swim() {
        console.log('游泳3')
    } 
}

let person3 = new Person3;
person3.fly();
person3.swim();

// 总结:接口与接口时间叫做继承(extends),类与接口之间叫做实现(implements)
console.log('类2')
 // 类:可以理解为模板,通过模板可以实例化对象
 // 面向对象的编程思想
 class Person{
     //定义属性
     name:string
     age:number
     gender:string

     // 定义构造函数,为了将来实例化对象的时候,可以直接对属性的值进行初始化
     constructor(name:string='gtt',age:number = 13,gender:string='女'){
         //更新对象中的属性数据
         this.name = name
         this.age = age
         this.gender = gender
     }

     // 定义实例方法
     sayHi(str:string){
         console.log(`大家好,我是${this.name},今年${this.age}岁了,是个${this.gender}孩`,str)
     }
 }

 const person = new Person();
 person.sayHi('自我介绍');//大家好,我是gtt,今年13岁了,是个女孩 自我介绍

 const person1 = new Person('小明',12,'男');
 person1.sayHi('自我介绍');//大家好,我是小明,今年12岁了,是个男孩 自我介绍
11、继承
console.log('继承')
// 继承:类与类之间的关系
// 继承后 类与类 之间的叫法:
// 如:A类继承了B类,那么此时A类叫做子类,B类叫做基类
// 子类---派生类
// 基类---超类(父类)
// 一旦发生了继承关系,就出现了父子类的关系(叫法)

// 1、定义一个类作为基类(超类/父类)
class Person{
    // 定义属性
    name:string
    age:number
    gender:string

    // 定义构造函数
    constructor(name:string,age:number,gender:string){
        //更新属性数据
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    // 定义实例方法
    sayHi(str:string){
        console.log(`我是${this.name},今年${this.age},我是${this.gender}孩子`,str);
    }
}

//2、定义一个类继承自Person
class Student extends Person{
    constructor(name:string,age:number,gender:string){
        // 调用父类中的构造函数,使用super
        super(name,age,gender)
    }
    // 可以调用父类中的方法
    sayHi(str: string) {
        console.log('我是父类中的sayHi方法')
        super.sayHi(str);
    }
}

// 1、实例化Person
// 2、实例化Student
const person = new Person('小明',13,'男');
person.sayHi('haha');//我是小明,今年13,我是男孩子 haha

const stu = new Student('小倪v',12,'女');
stu.sayHi('嘻嘻')//我是小倪v,今年12,我是女孩子 嘻嘻
12、多态
  console.log('多态');
// 多态:父类型的引用只想子类型的对象,不同类型的对象针对相同的方法,产生了不同的行为

// 1、定义一个父类
class Animal{
   // 定义一个属性
   name:string
   // 定义一个构造函数
   constructor(name:string){
       // 更新属性值
       this.name = name
   }
   // 实例方法
   run(distance:number=0){
       console.log(`跑了${distance}米`,this.name)
   }
}

// 2、定义一个子类
class Dog extends Animal{
   // 构造函数
   constructor(name:string){
       // 调用父类的构造函数,实现子类中属性的初始化操作
       super(name)
   }

   // 实例方法 重写父类中的实例方法
   run(distance:number=5){
       console.log(`跑了${distance}米`,this.name)
   }
}

// 3、再定义一个子类
class Pig extends Animal{
   constructor(name:string){
       super(name)
   }

  // 实例方法 重写父类中的实例方法
  run(distance:number=10){
   console.log(`跑了${distance}米`,this.name)
  }  
}


console.log('========1')
// 实例化父类对象
const ani:Animal=new Animal('动物');
ani.run(2)

// 实例化子类对象
const dog:Dog = new Dog('小狗')
dog.run();

// 实例化子类对象
const pig:Pig = new Pig('小狗')
pig.run();



//父类和子类的关系:父子关系,此时,父类类型创建子类的对象
console.log('========2')
const pig1:Animal = new Pig('猪猪');
pig1.run();

const dog1:Animal = new Dog('狗狗')
dog1.run();

console.log('=========3')
// 不同类型的对象针对相同的方法,产生了不同的行为 叫多态  有什么用处?
// 调用的是子类中自己的方法
// 定义一个函数需要的参数是Animal类型的
function showMsg(ani:Animal){
    ani.run()
}
 showMsg(dog1);
 showMsg(pig1)

在这里插入图片描述

13、修饰符:公共、私有与受保护的修饰符
// 修饰符(类中成员的修饰符):主要描述类中的成员(属性,构造函数,方法)的可访问性
// 类中的成员有自己默认的修饰符 public
// public 类中成员的默认修饰符,代表的是公共的,任何位置都可以访问类中的成员
// private修饰符 类中成员如果使用private来修饰,那么外部是无法访问这个成员数据的,当然子类中也是无法访问该成员数据的
// protected修饰符  类中成员如果用protected来修饰,那么外部是无法访问这个成员数据的,当然,子类中是可以访问该成员数据的
(()=>{
    class Person{
        // 定义属性
        public name:string
        // private name:sring
        protected age:number

        // 构造函数
        // new Person的时候实际上就是在调用构造函数
        constructor(name:string){
            this.name = name
        }

        // 实例方法
        eat(){
            console.log('真好吃',this.name)
        }
    }
    const per1 = new Person('大骨头');
    console.log(per1.name);//'大骨头';
    per1.eat();
})()
13.1 readonly修饰符
  • readonly修饰类中的属性值
// readonly修饰符:是一个关键字,对类中的属性成员进行修饰,修饰后该属性成员就不能再外部被随意的修改了
// 构造函数中,可以对只读 属性的成员进行数据修饰
// 如果构造函数中没有任何参数,类中的属性成员已经用readonly进行修饰,那么外部也是不能对这个属性值进行修改的

(()=>{
class Person{
    readonly name:string

    constructor(name:string) {
        this.name = name
    }

    play(){
        // 类中的普通方法中也不能修改readonly修饰的成员属性值
        console.log('撕吧新歌',this.name);
    }
}

// 实例化对象
const per:Person = new Person('小甜甜')
console.log(per)
console.log(per.name)
console.log(per.play())
// per.name ='大婷婷' 当时用readonly时此处报错,就不能被修改了
console.log(per.name)
  • 修饰构造函数中的参数属性
  //修饰构造函数中的参数属性

class Person{
    // 构造函数
    // 构造函数中的name参数,一旦使用readonly进行修饰后,那么name属性就可以教参数属性
    // 那么Person中就有了一个name的属性成员
    // 外部也是无法修改类中的name属性成员值得
    constructor(readonly name:string) {
        this.name = name
    }
    // public修饰后那么Person类中就有了一个公共的name属性成员了
    // constructor(public name:string) {
    //     this.name = name
    // }


    // private修饰后那么Person类中就有了一个私有的name属性成员了
    // constructor(private name:string) {
    //     this.name = name
    // }

    // protected修饰后那么Person类中就有了一个受保护的name属性成员了只能在本类和派生类中保护和使用了
    // constructor(protected name:string) {
    //     this.name = name
    // }

    play(){
        // 类中的普通方法中也不能修改readonly修饰的成员属性值
        console.log('撕吧新歌',this.name);
    }
}

// 实例化对象
const per:Person = new Person('小甜甜')
console.log(per)
console.log(per.name)
console.log(per.name)
13.2存取器
// 存取器:让我们可以有效的控制对象中成员的存取操作,通过getters和setters来进行操作
// 外部传入的数据可以通过set get进行控制,外部也可以进行修改
 class Person{
     firstName:string
     lastName:string

     constructor( firstName:string,lastName:string){
         this.firstName = firstName
         this.lastName = lastName
     }

     // 读取器-----负责读取数据的
     get fullName(){
         console.log('get---------')
         return this.firstName+'_'+this.lastName;
     }

     // 设置器-----负责设置数据的(修改)
     // 获取到名字重新赋值给firstName和lastName
     set fullName(val){
         console.log('set-------')
        let names = val.split('_');
        this.firstName = names[0];
        this.lastName = names[1]; 
     }
 }

 // 实例化对象
 const name1:Person = new Person('东方','不败');
 console.log(name1.fullName);

 // 设置该属性的数据
 name1.fullName = '诸葛_孔明';
 console.log(name1.fullName);
13.3静态成员
// 静态成员:在类中通过static修饰的属性或方法,就是静态的属性以及方法,也称之为:静态成员
// 静态成员调用的时候通过类名.的方式来调用
class Person{

    static name1:string='小'

    // 构造函数不能通过static来进行修饰
    constructor(name:string){
        // 此时this是实例对象,name1是静态属性,不能通过实例对象直接调用静态方法来使用
        // this.name1 = name
    }

    // 静态方法
    static sayHi(){
        console.log('nihao')
    }
}

// let per:Person = new Person('小雨');
// 通过实例调用的属性(实例属性)
// console.log(per.name1)
// 通过实例调用的方法(实例方法)
// per.sayHi()

// 通过类名.的形式直接访问 可以不用实例化对象了
console.log(Person.name1)

Person.sayHi();

// 也可以直接设置该成员属性数据
Person.name1 ='佐助'

console.log(Person.name1)
13.3抽象类
// 定义一个抽象类
// 抽象类:包含抽象方法(抽象方法一般没有任何的具体内容的实现),也可以包含实例方法
// 抽象类是不能被实例化的,为了让子类进行实例化以及实现内部的抽象方法

// 抽象类的目的或作用最终都是为子类服务
(()=>{
abstract class Animal{
     // 抽象属性
     abstract name:string

     // 抽象方法
     // 报错:抽象方法不能有具体的实现
     // abstract eat(){
     //     console.log('跳着吃')
     // }
     abstract eat()
     // 不同动物有不同的吃的方式(狗、鸟)因此需要抽象化  在具体的子类中实现

     // 实例方法
     sayHi(){
         console.log('你好啊',this.name)
     }
 }


 // 报错: 不能实例化抽象类
 // const ani:Animal = new Animal('黄')

 class Dog extends Animal{
     name:string='小黄'
     // 重新实现抽象类中的方法,此时这个方法就是当前Dog了的实例方法了
     eat(){
         console.log('舔着吃,真好吃')
     }
 }

 const dog:Dog = new Dog()
 dog.eat();

 dog.sayHi()

})()

在这里插入图片描述

14、函数
(()=>{
  console.log('函数')

  // js中的函数的写法

  // 1、函数声明,命名函数
  // function add(x,y){
  //     return x+y
  // }
  // 2、函数表达式,匿名函数
  // const add2 = function(x,y){
  //     return x+y
  // }

  // ts中的写法 函数中的参数一般会指定类型
  // 1、函数声明,命名函数
  function add(x:string,y:string):string{
      return x+y
  }

  const res1:string = add('111','222')
  console.log(res1)

  // 2、函数表达式,匿名函数
  const add2 = function(x:number,y:number):number{
      return x+y
  }

  const res2:number = add2(111,222)
  console.log(res2);

  // 函数的完整写法
  // add3======》变量名-----函数add3
  // (x:number,y:number)=>number当前的这个函数的类型
  // function(x:number,y:number):number{return x+y} 相当于符合上面这个函数的类型

  const add3:(x:number,y:number)=>number=function(x:number,y:number):number{
      return x+y
  }
})()
14.1函数可选参数
  (()=>{
 // 可选参数:函数声明时,内部的参数用?号进行修饰,就表示该参数可传可不传
  // 默认参数:函数在声明的时候,内部参数有自己的默认值

  // 定义一个函数 当姓 名都有得到姓名,否则得到姓氏
  const getName = function(firstName:string='东方',lastName?:string):string{
      if(lastName){
          return firstName+'_'+lastName;
      }else{
          return firstName
      }       
      
  }

  // 无参
  console.log(getName());//东方
  // 单参
  console.log(getName('诸葛'));//诸葛
  //双参
  console.log(getName('诸葛','孔明'))
  })()
14.2剩余参数
(()=>{
    // 剩余参数是放在函数声明的所有参数的最后

    //...args:string[]-----剩余参数,放在了一个字符串的数字中,args里面
    function showMsg(str:string,...args:string[]){
       console.log(str);'a'
       console.log(args);['b','c','d']
    }

    showMsg('a',"b","c","d")
})()
14.3函数的重载声明
// 函数重载:函数的名字相同,函数的参数以及个数不同
(()=>{
// 定义一个函数
// 函数重载声明
function add(x:string,y:string):string
function add(x:number,y:number):number

// 需求:有一个add函数,可以接收两个string|number参数进行拼接或相加
function add(x:string|number,y:string|number):string|number{
    if(typeof x==='string'&&typeof y==='string'){
        return x+y
    }else if(typeof x==='number'&& typeof y==='number'){
        return x+y
    }
}

//函数调用
console.log(add('诸葛','孔明'));
console.log(add(100,200));

// 当参数的形式不符合条件时  这时候就需要我们使用函数重载声明
// 如:add('小明',100) 这时就会报错

// 如上 对函数的参数进行重载声明
})()
15、泛型
(()=>{
  console.log('泛型')
  // 在定义函数、接口、类的时候不能预见确定要是用的数据类型,而是在使用的时候才能确定

  // 需求:定义一个函数,传入两个参数 第一个是数据 第二个是参数的数量
  // 函数的作用:根据数量 创建一个对象数量的数据 数组并且返回

  // 当全是数字时
  function getArr(value:number,count:number):number[]{
      const arr:number[]=[]
      for(let i=0;i<count;i++){
          arr.push(value);
      }
      return arr
  }

  // 但是当需求改变 传入的是字符 需要返回字符数组的时候 我们定义的函数就不能使用了
  // 这个时候就需要泛型
  // 可以使用any类型还注解

  // 但是会发现问题  当数字时我们对数字使用.toFixed()方法或者对string使用split方法时并不会提示
  // 所以我们使用泛型
  function getArr4<T>(value:T,count:number):T[]{
      const arr:Array<T>=[]
      for(let i=0;i<count;i++){
          arr.push(value)
      }
      return arr
  }
  const arr1=getArr4(200.123,4);
  const arr2 = getArr4('abc',6)
  console.log(arr1[0].toFixed(2));//会有提示 说明arr1[0]为number类型 同理string split()方法
})()
15.1多个泛型参数的函数
(()=>{
 // 泛型字母通常可以说使用大写字母 T、K、V

  function getMsg<K,V>(value:K,value2:V):[K,V]{
      return [value,value2]
  }

  const arr1 = getMsg<string,number>('jack',123.12)
  console.log(arr1[0].split(''))
  console.log(arr1[1].toFixed(1))
})
15.3 泛型 接口
在这里插入代码片
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值