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。
持续更新