1.Typescript
1.编程语言的类型
1.2javascript
1.3为什么要使用Typescript
1.4安装Typescript
1.5创建test.ts文件
1.6生成js文件
1.7原始类型
1.8数组和元组
1.9Interface接口
2.0Function函数
2.1类型推论 断言联合类型和类型
2.2类Class
2.3.类和接口
3.4枚举
3.5泛型
3.6约束泛型
3.在类和接口中使用77泛型
3.8类型别名 字面量和交叉类型
3.9声明文件
4.0内置类型
2.组件创建应用
2.1创建
2.2引用
2.在组件中使用v-modele实现双向绑定
2.4非 Prop 的 Attribute
1.Typescript
1.编程语言的类型
1.动态语言 只有在运行时间知道代码的值 2.静态语言 定义代码类型
1.2javascript
1.可扩展的javascript 2.静态类型风格类型系统 3.从es6到es10甚至是esnext的语法支持 4.兼容浏览器、系统、服务器、开源 5.增强id和编辑功能
1.为什么要用?Typescript
1.程序更容易理解 2.效率更高 3.可以在不同的代码块和定义中跳转 4.自动补充代码 5.编译期间能够发现大部分错误 6.杜绝一些常见的错误 7.增加学习成本 8.短期内增加一些开发成本
1.4安装Typescript
# 全局安装tsc 指定版本 npm install -g typescript@3.8.3 # 查看当前版本号 tsc -v
1.5创建test.ts文件
const hello =(name:string)=>{ return `hellow ${name}` } hello('bus')
1.6生成js文件
#执行文件目录cmd 命令 tsc test.ts
1.7原始类型
let isDone: boolean =false; let age: number = 10; let firstName: string = "12"; let u:undefined = undefined; let n:null = null; let num: number = undefined; let userName:string = null; /*任意类型*/ let notSure: any = 4; notSure = "1231"; notSure = true;
1.8数组和元组
/*数组*/ let arrayOfNumbers: number[] = [1,2,3,4]; arrayOfNumbers.push(4) function test(){ console.log(arguments) } /*元组*/ let user:[string,number] = ['busl',2] /*指定push string number 两种类型*/ user.push(12)
1.9Interface接口
//对象形状(shape)进行描述 //Duck Typing (鸭型) // 定义对象类型属性规则 /* * ? 这个属性可选可不选 * readonly 只读不能赋值 * * */ interface Person{ readonly id: number; name:string; age?:number; } let viking: Person = { id:1, name:"busl", age:20 }
2.0Function函数
// 定义参数类型和返回类型 ?可选 const add=(x:number,y:number,z?:number): number=>{ if(typeof z == 'number'){ return x +y +z }else{ return x+y } } let result = add(1,2); interface ISum{ (x:number,y:number,z?:number):number } let add1:ISum = add; //: 后面声明类型 let add2:(x:number,y:number,z?:number)=>number=add;
2.1类型推论 联合类型和类型断言
//联合类型 union types ,可以给一个值定义两个类型 let numberOrString: number | string numberOrString = 'adc' numberOrString = 123 //但之后只能访问两个类型的共有方法 使用类型断言 function getLength(input:string | number): number{ const str = input as string if(str.length){ return str.length }else{ const number = input as number return number.toString().length } } // type guard 自动缩小类型范围,改写上面函数 function getLength2(input:string | number): number{ if(typeof input=="string"){ return input.length }else{ return input.toString().length } }
2.2类Class
1.类:定义了一切事物的抽象特点 2.对象:类的实例 3.面向对象oop三大特性:封装、继承、多态 4.Public:修饰的属性或者方法是公有的 5.private:修饰的属性或方法是私有的 6.Protected:修饰的属性或方法是受保护的 class Animal { name: string; constructor(name) { this.name = name; } public run() { return `${this.name} is runing ` } } const snake = new Animal("busl") console.log(snake.run()) //继承 class Dog extends Animal { private bark() { return `${this.name} is barking` } } const xiaobao = new Dog("xiaobao"); console.log(xiaobao.run()) console.log(xiaobao.bark()) //多态 class Cat extends Animal{ static categories = ["mammal"] constructor(name) { super(name); console.log(this.name) } run(){ return "meow:" +super.run() } } const maomao = new Cat("maomao"); console.log(maomao.run()) //类上面直接访问的属性和方法 console.log(Cat.categories)
2.3.类和接口
//类可以使用implements 来实现接口 interface Radio{ sswitchRadio(trigger: boolean): void } interface Battery{ checkBatterStatus(): void } interface RadioWithBattery extends Radio{ checkBatterStatus(): void } class Car implements Radio{ sswitchRadio(trigger: boolean): void { } } class Cellphone implements Radio,Battery{ sswitchRadio(trigger: boolean): void { } checkBatterStatus(): void { } } class Cellphone2 implements RadioWithBattery{ sswitchRadio(trigger: boolean): void { } checkBatterStatus(): void { } }
3.4枚举
// 不会被改变 enum Direction{ Up="UP", Down="DOWN", Left="LEFT", Right="RIGHT" } // UP console.log(Direction.Down) // UP console.log(Direction[0])
3.5泛型
function echo<T>(arg:T):T { return arg; } // 指定变量类型 const str: string = 'str' const result = echo(str); //也可以不指定 const result2 = echo("str2"); //多个 function swap<T,U>(tuple: [T,U]):[U,T]{ return [tuple[1],tuple[0]] } const result3 = swap(['string',123]); console.log(result3)
3.6约束泛型
function echo<T>(arg:T):T { return arg; } // 指定变量类型 const str: string = 'str' const result = echo(str); //也可以不指定 const result2 = echo("str2"); //多个 function swap<T,U>(tuple: [T,U]):[U,T]{ return [tuple[1],tuple[0]] } const result3 = swap(['string',123]); console.log(result3) //约束泛型,允许传入指定值的类型 function echoWithArr<T>(arg:T[]): T[]{ console.log(arg.length) return arg; } const arrs = echoWithArr([1,2,3]); interface IWithLength{ length: number } function echoWithArrLength<T extends IWithLength>(arg: T):T{ console.log(arg.length) return arg; } console.log(echoWithArrLength(["123",1,2,4])) console.log(echoWithArrLength({length:10,width:10})) console.log(echoWithArrLength([1,2,3])) //错误 //console.log(echoWithArrLength(13))
3.7泛型在类和接口中使用
const queue = new Queue<number>(); queue.push(1) console.log(queue.pop().toFixed()) interface KeyPair<T,U> { key:T value:U } let kp1:KeyPair<number, string> = {key:1,value:"string"} let kp2:KeyPair<string, number> = {key:"string",value:1} let arr: number[] = [1,2,3] let arrTwo: Array<number> = [12,123,1234]
3.8类型别名 字面量和交叉类型
//类型别名 let sum: (x: number,y: number) => number; const result = sum(1,2); type PlusType = (x: number,y: number) => number; let sum2 : PlusType; const result2 = sum2(2,3); type StringOrNumber = string | number; let result3 :StringOrNumber = "123"; result3 = 123; //字面量 const str:'name' = 'name'; const number:1=1; // 交叉类型 type Directions = 'Up' | 'Down' | 'Left' | 'Right'; let toWhere:Directions = 'Left'; //组合类型 interface IName{ name:String } type IPerson = IName & {age:number} let person : IPerson = {name:"123",age:1}
3.9声明文件
//安装jquery npm install --save @types/jquery //安装源代码 npm install --save redux jQuery("#foo"); //引入源代码 import {Action} from 'redux';
4.0内置类型
1.全局存在的对象,在每个项目中会自动加载 const a:Array<number> =[123,123,231]; const data = new Date(); data.getTime() const reg = /abc/; reg.test('abc'); Math.pow(2,2) let body = document.body let allLis = document.querySelectorAll("li"); allLis.length document.addEventListener('check',(e)=>{ }) interface IPerson{ name:string age:number } let viking :IPerson ={name:"busl",age:20} type Ipartial = Partial<IPerson>; //忽略属性 type IOmit=Omit<IPerson,"name"> let IOmit={age:12}
2.组件创建应用
2.1创建
<template> <div class="validate-input-container pd-3"> <label class="form-label">邮箱地址</label> <input type="email" class="form-control" :class="{'is-invalid': inputRef.error}" v-model="inputRef.val" @blur="validateInput" > <span class="invalid-feedback" v-if="inputRef.error"> { { inputRef.message }} </span> </div> </template> <script lang="ts"> import { defineComponent, reactive, PropType } from 'vue' const emailReg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/ interface RuleProp { type: 'required' | 'email' | 'length'; message: string; } export type RulesProp = RuleProp[] export default defineComponent({ props: { rules: Array as PropType<RulesProp> }, setup (props) { const inputRef = reactive({ val: '', error: false, message: '' }) const validateInput = () => { if (props.rules) { const allPassed = props.rules.every(rule => { let passed = true inputRef.message = rule.message switch (rule.type) { case 'required': passed = (inputRef.val.trim() !== '') break case 'email': passed = emailReg.test(inputRef.val) break default: break } return passed }) inputRef.error = !allPassed } } return { inputRef, validateInput } } }) </script> <style scoped> </style>
2.2引用
<template> <!--container: 居中容器 --> <div class="container"> <global-header :user="currentUser"></global-header> <form> <div class="mb-3"> <validate-input :rules="emailRules"></validate-input> </div> <div class="mb-3"> <label for="exampleInputPassword1" class="form-label">密码</label> <input type="password" class="form-control" id="exampleInputPassword1"> </div> <div class="mb-3 form-check"> <input type="checkbox" class="form-check-input" id="exampleCheck1"> <label class="form-check-label" for="exampleCheck1">Check me out</label> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> </template> <script lang="ts"> import { defineComponent, reactive } from 'vue' import 'bootstrap/dist/css/bootstrap.min.css' import GlobalHeader, { UserProps } from '@/components/GlobalHeaderName.vue' import ValidateInput, { RulesProp } from '@/components/ValidateInputName.vue' const currentUser: UserProps = { isLogin: true, name: 'busl', id: 1 } export default defineComponent({ name: 'App', components: { ValidateInput, GlobalHeader }, setup () { const emailRules: RulesProp = [ { type: 'required', message: '电子邮箱不能为空!' }, { type: 'email', message: '请输入正确的电子邮箱格式!' } ] const emailRef = reactive({ val: '', error: false, message: '' }) return { currentUser, emailRef, emailRules } } }) </script> <style> </style>
2.3在组件中使用v-modele实现双向绑定
// 组件改造 context.emit('update:modelValue', targetValue) <input type="email" class="form-control" :class="{'is-invalid': inputRef.error}" @input="updateValue" :value="inputRef.val" @blur="validateInput" > export default defineComponent({ props: { rules: Array as PropType<RulesProp>, modelValue: String }, setup (props, context) { const inputRef = reactive({ val: props.modelValue || '', error: false, message: '' }) const updateValue = (e: KeyboardEvent) => { const targetValue = (e.target as HTMLInputElement).value inputRef.val = targetValue context.emit('update:modelValue', targetValue) } const validateInput = () => { if (props.rules) { const allPassed = props.rules.every(rule => { let passed = true inputRef.message = rule.message switch (rule.type) { case 'required': passed = (inputRef.val.trim() !== '') break case 'email': passed = emailReg.test(inputRef.val) break default: break } return passed }) inputRef.error = !allPassed } } return { inputRef, validateInput, updateValue } } }) //引用改造 <div class="mb-3"> <validate-input :rules="emailRules" v-model="emailValue"></validate-input> { { emailValue }} </div> import { defineComponent, reactive, ref } from 'vue' setup () { const emailValue = ref('viking') const emailRules: RulesProp = [ { type: 'required', message: '电子邮箱不能为空!' }, { type: 'email', message: '请输入正确的电子邮箱格式!' } ] const emailRef = reactive({ val: '', error: false, message: '' }) return { currentUser, emailRef, emailRules, emailValue } }
2.4非 Prop 的 Attribute
一个非 prop 的 attribute 是指传向一个组件,但是该组件并没有相应 props 或 emits 定义的 attribute。常见的示例包括 class、style 和 id attribute。可以通过 $attrs property 访问那些 attribute。
持续更新