TypeScript快速上手语法+结合vue3用法
创始人
2024-06-03 15:19:30
0

 TypeScript快速上手语法+结合vue3用法

        前言:    

        本篇内容不涉及TypeScript安装以及配置,具体安装及配置篇可以看下面目录,本篇只涉及TypeScript语法相关内容,及结合vue3的用法。不讲废话,简单直接直接开撸。

目录

     TypeScript的具体安装及配置

 TypeScript快速上手语法+结合vue3用法

1、定义原始类型 

2、定义object 类型

3.定义数组类型 

4.定义元祖类型

5.定义enum 类型

6.定义函数类型

7.定义任意类型

8.隐式类型推断

9.类型断言

 10、 接口 interface

11、类 Class

12.类与接口

13.抽象类

   14. 泛型 Generics

Vue3+TS基础语法

🧨🧨🧨定义data

    🧨🧨🧨定义props

    🧨🧨🧨定义methods

vue-router

    在setup中使用

   🧨🧨🧨 vuex

在setup中使用

    模块

🧨🧨🧨 在setup如何定义变量(字符串,对象,数组)

Watch和WatchEffect

Vue3生命周期调用 


 

1、定义原始类型 

const a: string = 'foo'
const b: number = 100
const c: boolean = true
const d: void = undefined
const e: null = null
const f: undefined = undefined
const g: symbol = Symlol()

2、定义object 类型

const foo: object = function () {} // [] // {}
const obj: { foo: number,bar: string } = { foo: 123, bar: 'string' }

3.定义数组类型 

// 第一种定义方式,元素类型设置为 *number*
const arr1: Array = [1, 2, 3]
// 第二种定义方式,较为常见
const arr2: number[] = [1, 2, 3]// 例子
function sum (...args: number[]) {// 传统做法是要判断传入的参数是否是数字,而TypeScript中只需要像上面这样对参数做一个类型注解,就行了return args.reduce(prev, current) => prev + current, 0)
}sum(1, 2, 3, 'foo') // 这里传入了一个非数字的值就会报错

4.定义元祖类型

const tuple: [number, string] = [18, 'foo']
// const tuple: [number, string] = [18, 18] 类型不匹配,会报错
// const tuple: [number, string] = [18, 'foo', 'xxx'] 数量不匹配,会报错// 访问
const age = tuple[0]
const name = tuple[1]// 解构
const [age, name] = tuple

5.定义enum 类型

// enum 对象的属性可以不用赋值,默认从0开始递增,也可以赋值Draft = 5,后面的就从5开始递增也可以给具体的值,比如 Draft = 'xxx',这样后面的属性都要给具体的值
enum PostStatus {Draft = 0,Unpublished = 1,Published = 2
}const post = {title: 'Hello TypeScript',content: 'TypeScript is a typed superset of JavaScript.',status: PostStatus.Draft // 0 // 1 // 2
}

6.定义函数类型

// 声明式函数
// 参数a和b是number类型,函数返回是string类型,
// 参数后带问号代表是可选参数
// 当参数数量不固定的时候可以使用rest运算符来接受参数,类型是一个值为number的数组
function func1 (a: number, b?: number, ...rest: number[]): string {return 'func1'
}// 函数表达式定义函数
const func2 = function (a: number, b: number): string {return 'func2'
}// 如果把一个函数作为参数传递,类似callback函数。
function fntD(callback: (bl: boolean) => boolean) {callback(true)
}
function callback(bl: boolean): boolean {console.log(bl)return bl
}
const dResult = fntD(callback)

7.定义任意类型

// value 可以接受任意类型
function stringfy (value: any) {return JSON.stringify(value)
}stringify('string')
stringify(10)
stringify(true)// foo 可以任意赋值
let foo: any = 'string'
foo = 100

8.隐式类型推断

// age 赋值为 number 类型
let age = 18 // numberage = 'string' // 会警告错误,因为age是number类型let foo // 没有赋值,就是any类型foo = 100
foo = 'string'

9.类型断言

// 假定这个 nums 来自一个明确的接口
const nums = [110, 120, 119, 112]// 这里TypeScript推断res的类型为 number|undefined
// 因为它并不知道这个i到底在数组中有没有
const res = nums.find(i => i > 0)// 这里就会报错警告
const square = res * res// 如果我们直接 断言 这个 res 就是 number 类型
const num1 = res as number// 这里就不会报错了
const square = res * res

 10、 接口 interface

接口用来约定对象的结构,一个对象要实现一个接口,就必须拥有这个接口中所包含的所有成员

interface Post {title: stringcontent: string
}function printPost (post: Post) {console.log(post.title)console.log(post.content)
}printPost({title: 'Hello TypeScript',content: 'A JavaScript superset'
})// 特殊的接口成员 可选成员 只读成员
interface Post{title: stringcontent: stringsubtitle?: string // 加问号就是可选成员readonly summary: string // 加 readonly 就是只读成员
}const hello: Post = {title: 'Hello TypeScript',content: 'A javascript superset',summary: 'a javascript'
}hello.summary = 'other' // 会报错,因为 summary 是只读成员// 动态成员
interface Cache {[prop: string]: string
}const cache: Cache = {}cache.foo = 'value1'
cache.bar = 'value2'

11、类 Class

Class Person {// 在这里赋值,和在构造函数中初始化必须两者选其一name: string // = 'init name' 这里可以直接初始化private age: number // 这里定义 age 为私有属性protected gender: boolean // 受保护的类型readonly national: string // 只读属性,一经初始化,不可更改constructor (name: string, age: number) {// 需要在上面标注出构造函数中属性的类型this.name = namethis.age = agethis.gender = truethis.national = national}sayHi (msg: string): void {console.log(`I am ${this.name}, ${msg}`)console.log(this.age)}
}const tom = new Person('tom', 18)
console.log(tom.name) // tom
console.log(tom.age) // 报错,因为 age 是私有属性,所以访问不到
console.log(tom.gender) // 报错,因为 gender 是受保护的属性,这里访问不到// 在下方新声明一个类 student 继承与 Person
class Student extends Person {constructor (name: string, age: number) {super(name, age)console.log(this.gender) // 这里就一个访问到 受保护的属性 gender
}

12.类与接口

interface Eat {eat (food: string): void
}interface Run {run (distance: number): void
}// Person类,实现了 Eat 和 Run 两个接口
class Person implements Eat, Run {eat (food: string): void {console.log(`优雅的进餐:${food}`)}run (distance: number) {console.log(`直立行走:${distance}`)}
}// Animal类,实现了 Eat 和 Run 两个接口
class Animal implements Eat, Run {eat (food: string): void {console.log(`饥不择食的吃:${food}`)}run (distance: number) {console.log(`爬行:${distance}`)}
}

13.抽象类

    abstract 定义抽象类,抽象类只能被继承,不能通过 new 的方式创建实例对象

// 定义一个抽象类 Animal
abstract class Animal {eat (food: string): void {console.log(`饥不择食的吃:${food}`)}// 定义一个抽象方法 run,可以不需要方法体。// 定义了抽象方法之后,子类中必须实现这个抽象方法abstract run (distance: number): void
}class Dog extends Animal {run(distance: number): void {console.log('四脚爬行', distance)}
}const d = new Dog()
d.eat('嘎嘎') // 饥不择食的吃:嘎嘎
d.run(100) // 四脚爬行 100

   14. 泛型 Generics

    泛型是指在定义接口函数类的时候,没有指定具体的类型,等到我们在使用的时候再去指定具体的类型的这种特征

// 这里声明一个创建 number 类型数组的函数 creatNumberArray
function createNumberArray (length: number, value: number): number[] {// 这里的Array是 any 类型,所以要给它指定一个 Number 类型const arr = Array(length).fill(value)return arr
}// 这里声明一个创建 String 类型数组的函数 createStringArray
function createStringArray (length: number, value: string): string[] {const arr = Array(length).fill(value)return arr
}// 因为上面的两个函数代码有冗余,所以这里我们可以使用 泛型
// 一般我们使用 T 来作为泛型参数的名称,然后把函数中不明确的类型都改为 T 来做代表
function createArray (length: number, value: T): T[] {const arr = Array(length).fill(value)return arr
}// 然后使用泛型的时候 传递 T 的类型
const res = creatArray(3,'foo')// const res = createNumberArray(3, 100)
// res => [100, 100, 100]

==============================分割线=============================

下面是结合vue3的项目写法

Vue3+TS基础语法

🧨🧨🧨定义data

  • script标签上lang="ts"

  • 定义一个类型type或者接口interface来约束data

  • 可以使用ref或者toRefs来定义响应式数据

  • 使用ref在setup读取的时候需要获取xxx.value,但在template中不需要

  • 使用reactive时,可以用toRefs解构导出,在template就可以直接使用了

    🧨🧨🧨定义props

    props需要使用PropType泛型来约束。


复制代码

defineProps 和 defineEmits 

    注意:defineProps 和 defineEmits 都是只在

    为了声明 props 和 emits 选项且具备完整的类型推断,可以使用 defineProps 和 defineEmits API,它们在

 子组件

//子组件

 子组件暴露属性和方法,给父组件引用


父组件调用子组件方法和属性 



    🧨🧨🧨定义methods

vue-router

  •     createRouter创建router实例
  •     router的模式分为:
  •     createWebHistory -- history模式
  •     createWebHashHistory -- hash模式
  •     routes的约束类型是RouteRecordRaw
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
import Home from '../views/Home.vue';
const routes: Array< RouteRecordRaw > = [{path: '/',name: 'Home',component: Home,},{path: '/about',name: 'About',component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')}
];const router = createRouter({history: createWebHistory(process.env.BASE_URL),routes
});export default router;

    扩展路由额外属性

    在实际项目开发中,常常会遇到这么一个场景,某一个路由是不需要渲染到侧边栏导航上的,此时我们可以给该路由添加一个hidden属性来实现。

    在ts的强类型约束下,添加额外属性就会报错,那么我们就需要扩展RouteRecordRaw类型。

    在setup中使用

    需要导入useRouter创建一个router实例。


   🧨🧨🧨 vuex

    使用this.$store

import { createStore } from 'vuex';
export type State = {count: number
}export default createStore({state: {count: 0}
});

    需要创建一个声明文件vuex.d.ts

// vuex.d.ts
import {ComponentCustomProperties} from 'vue';
import {Store} from 'vuex';
import {State} from './store'
declare module '@vue/runtime-core' {interface ComponentCustomProperties {$store: Store}
}

在setup中使用

  •  定义InjecktionKey
  • 在安装插件时传入key
  • 在使用useStore时传入
import { InjectionKey } from 'vue';
import { createStore, Store } from 'vuex';export type State = {count: number
}
// 创建一个injectionKey
export const key: InjectionKey> = Symbol('key');
// main.ts
import store, { key } from './store';
app.use(store, key);

    模块

    新增一个todo模块。导入的模块,需要是一个vuex中的interface Module的对象,接收两个泛型约束,第一个是该模块类型,第二个是根模块类型。

// modules/todo.ts
import { Module } from 'vuex';
import { State } from '../index.ts';type Todo = {id: number,name: string,completed: boolean
}const initialState = {todos: [] as Todo[]
};export type TodoState = typeof initialState;export default {namespaced: true,state: initialState,mutations: {addTodo (state, payload: Todo) {state.todos.push(payload);}}
} as Module; //Module S 该模块类型 R根模块类型
// index.ts
export type State = {count: number,todo?: TodoState // 这里必须是可选,不然state会报错
}export default createStore({state: {count: 0}modules: {todo}
});

    使用: 

setup () {console.log(store.state.todo?.todos);
}

🧨🧨🧨 在setup如何定义变量(字符串,对象,数组)



Watch和WatchEffect

    1、基本使用方法:



提示:

watch与 watchEffect 比较,推荐watch监听

watch: 页面更新后不会立即执行,而watchEffect 它会执行;

🧨🧨🧨Vue3生命周期调用 

在 setup () 内部调用生命周期钩子:

  •     选项式 API Hook inside setup
  •     beforeCreate Not needed* 不需要
  •     created Not needed* 不需要
  •     beforeMount onBeforeMount 挂载之前
  •     mounted onMounted 页面加载完成时执行
  •     beforeUpdate onBeforeUpdate
  •     updated onUpdated
  •     beforeUnmount onBeforeUnmount
  •     unmounted onUnmounted 页面销毁时执行
  •     errorCaptured onErrorCaptured
  •     renderTracked onRenderTracked
  •     renderTriggered onRenderTriggered
  •     activated onActivated
  •     deactivated onDeactivated

 


加🧨🧨🧨为必用的东西,可以多看看

 最后:

        待续....精力有限 持续更新中....

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...
带头循环双向链表来咯!!! 前言:继上文,我们了解了结构最简单的一种链表---单链表那么我们今天就来...