群晖wordpress远程安装,镇江网站优化公司工作室,影业的网站怎么做,绍兴seo全网营销TypeScript快速上手语法结合vue3用法 前言#xff1a; 本篇内容不涉及TypeScript安装以及配置#xff0c;具体安装及配置篇可以看下面目录#xff0c;本篇只涉及TypeScript语法相关内容#xff0c;及结合vue3的用法。不讲废话#xff0c;简单直接直接开撸。 目录 Type… 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
Vue3TS基础语法
定义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: Arraynumber [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 value211、类 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 Arraynumber(length).fill(value)return arr
}// 这里声明一个创建 String 类型数组的函数 createStringArray
function createStringArray (length: number, value: string): string[] {const arr Arraystring(length).fill(value)return arr
}// 因为上面的两个函数代码有冗余所以这里我们可以使用 泛型
// 一般我们使用 T 来作为泛型参数的名称然后把函数中不明确的类型都改为 T 来做代表
function createArrayT (length: number, value: T): T[] {const arr ArrayT(length).fill(value)return arr
}// 然后使用泛型的时候 传递 T 的类型
const res creatArraystring(3,foo)// const res createNumberArray(3, 100)
// res [100, 100, 100]分割线
下面是结合vue3的项目写法 Vue3TS基础语法 定义data script标签上langts 定义一个类型type或者接口interface来约束data 可以使用ref或者toRefs来定义响应式数据 使用ref在setup读取的时候需要获取xxx.value,但在template中不需要 使用reactive时可以用toRefs解构导出在template就可以直接使用了 script langts
import { defineComponent, reactive, ref, toRefs } from vue;type Todo {id: number,name: string,completed: boolean
}export default defineComponent({const data reactive({todoList: [] as Todo[]})const count ref(0);console.log(count.value)return {...toRefs(data)}
})
/script 定义props props需要使用PropType泛型来约束。
script langts
import { defineComponent, PropType} from vue;interface UserInfo {id: number,name: string,age: number
}export default defineComponent({props: {userInfo: {type: Object as PropTypeUserInfo, // 泛型类型required: true}},
})
/script
复制代码 defineProps 和 defineEmits 注意defineProps 和 defineEmits 都是只在 为了声明 props 和 emits 选项且具备完整的类型推断可以使用 defineProps 和 defineEmits API它们在 script setup 中都是自动可用的 defineProps 和 defineEmits 都是只在 script setup 中才能使用的****编译器宏。他们不需要导入且会在处理 script setup 的时候被编译处理掉。 defineProps 接收与 props 选项相同的值defineEmits 也接收 emits 选项相同的值。 defineProps 和 defineEmits 在选项传入后会提供恰当的类型推断。 传入到 defineProps 和 defineEmits 的选项会从 setup 中提升到模块的范围。因此传入的选项不能引用在 setup 范围中声明的局部变量。这样做会引起编译错误。但是它可以引用导入的绑定因为它们也在模块范围内。父组件
//父组件script setup langtsimport TestPropsPmit from ./components/test-props-emit/index.vue;import { ref } from vue;// 定义字符串变量const msg ref(欢迎使用vite)// 调用事件const handleChange (params:string) {console.log(params);}
/script
templateTestPropsPmit :msgmsg on-changehandleChange/TestPropsPmit
/template子组件
//子组件templatep{{props.msg}}/pbutton clickhandleClick点击我调用父组件方法/button
/template
script setup langtsconst props defineProps({msg:{type: String,default: () 默认值}})const emit defineEmits([on-change, update])const handleClick () {emit(on-change, 父组件方法被调用了)}
/script子组件暴露属性和方法给父组件引用
script setup langts
function testChild():void{console.log(子组件方法testChild被调用了);
}
const b ref(2)
// 统一暴露属性
defineExpose({obj:{name: 张三, age: 2300},b,testChild
})
/script父组件调用子组件方法和属性
templateTestPropsEmit refpropsEmitRef :msgmsg on-changehandleChange /TestPropsEmit
/template
script setup langtsimport TestPropsEmit from ./components/test-props-emit/index.vue;import {ref, onMounted} from vue;const msg ref(欢迎学习vite)const handleChange (params:string){console.log(params);}const propsEmitRef ref()onMounted((){console.log(propsEmitRef.value.child);})
/script定义methods script langts
import { defineComponent, reactive, ref, toRefs } from vue;type Todo {id: number,name: string,completed: boolean
}export default defineComponent({const data reactive({todoList: [] as Todo[]})// 约束输入和输出类型const newTodo (name: string):Todo {return {id: this.items.length 1,name,completed: false};}const addTodo (todo: Todo): void {data.todoList.push(todo)}return {...toRefs(data),newTodo,addTodo}
})
/script vue-router createRouter创建router实例 router的模式分为 createWebHistory -- history模式 createWebHashHistory -- hash模式 routes的约束类型是RouteRecordRawimport { 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实例。
script langts
import { useRouter } from vue-router;
import { defineComponent } from vue;
export default defineComponent({setup () {const router useRouter();goRoute(path) {router.push({path})}}
})
/scriptvuex 使用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: StoreState}
}在setup中使用 定义InjecktionKey在安装插件时传入key在使用useStore时传入import { InjectionKey } from vue;
import { createStore, Store } from vuex;export type State {count: number
}
// 创建一个injectionKey
export const key: InjectionKeyStoreState Symbol(key);// main.ts
import store, { key } from ./store;
app.use(store, key);
script langts
import { useStore } from vuex;
import { key } from /store;
export default defineComponent({setup () {const store useStore(key);const count computed(() store.state.count);return {count}}
})
/script 模块 新增一个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 ModuleTodoState, State; //ModuleS, R 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如何定义变量(字符串,对象,数组) templateh2{{count}} {{user.name}}/h2span v-for(item, index) in arr :keyindex{{item}}/spanbutton clicksetName点击我增加/button
/template
script setup langtsimport { ref, reactive } from vue;// 字符串变量const count ref(0)// 对象let user reactive({name: 张三})// 数组let arr reactive([1, 2, 3])// 综合定义方案const originData reactive({count: 0,user:{name: 张三},arr: [1, 2, 3]})// 方法const setName (){count.valueuser.name 李四}
/scriptWatch和WatchEffect 1、基本使用方法
templatep{{originData.count}} {{originData.user.name}}/pp v-for(item, index) in originData.arr :keyindex{{item}}/pbutton clickincriment点击我count增加/button
/template
script setup langtsimport { ref, reactive, watchEffect, watch } from vue;const count ref(0)const user reactive({name: 张三})const arr reactive([1,2,3,4])// 综合定义方案const originData reactive({count: 0,user:{name: 张三},arr:[1,2,3,4]})const incriment (){originData.countcount.valueoriginData.user.name 李四}// 默认页面更新之前立即执行监听懒执行开始watchEffect(() console.log(count.value))// 默认监听数据变化后的值页面更新后不会立即执行watch(count, (n, o) {console.log(watch, n, o);})// 监听多个值watch([count, originData.user], (newValues, prevValues) {console.log(newValues[0], newValues[1].name)})// 立即监听watch([count, originData.user], (newValues, prevValues) {console.log(newValues[0], newValues[1].name)}, {deep: true, immediate: true})/script提示 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 script setup langts
import { onMounted, onActivated, onUnmounted, onUpdated, onDeactivated } from vue;
// 读取环境变量
const mode import.meta.env;
// import HeadMenu from /components/head-menu/index.vue;onMounted(() {console.log(组件挂载)})onUnmounted(() {console.log(组件卸载)})onUpdated(() {console.log(组件更新)})onActivated(() {console.log(keepAlive 组件 激活)})onDeactivated(() {console.log(keepAlive 组件 非激活)})
/script加为必用的东西可以多看看 最后 待续....精力有限 持续更新中....