前言:
记录Yang的Vue3.2+vite+TS入门学习总结,可供萌新朋友们参考
该笔记分为Vue3.2和TS入门两个部分
大佬们推荐的实用工具:
✅脚手架:vite
✅路由:vue-router4
✅状态管理:pinia
✅Hooks库:vueuse
✅自动导入插件(懒人必备):unplugin-vue-components、unplugin-auto-import/vite
Vue3.2
思考:为什么特意说时3.2而不是3.x呢?
答:因为3.2版本出现了人见人爱的setup语法糖
-Vue3组合式API与Vue2配置项的差别
下面是Vue3.2组合式api的一个小demo:
<script setup >
import {ref,reactive,onMounted,defineProps,defineEmits} from 'vue'
let my_name = ref('Yang')
let person= reactive({
name:'Yang'
age:18
pet:{
pet_name:'小白'
pet_age:3
}
playBasketBall(){
console.log('洋仔正在打篮球')
}
})
function doSomething(someone,dosomething){
console.log(`${someone}正在${dosomething}!`)
}
onMounted(()=>{
console.log('挂载成功!')
})
//父子传参
const props = defineProps({
foo: String
})
const emit = defineEmits(['change', 'delete'])
-----------------------------------------------------------
console.log(my_name.value)
//输出结果:Yang
<script>
demo出现的几个基本API:
ref---使基本数据类型变为响应式,但在js中使用时要得到数据必须.value,vue实例中不用.value
reactive---使复杂数据类型变为响应式
moMounted---生命周期钩子
defineProps,defineEmits---父子传参
还有未出现的很多基本api如computed,watch等等,这些api与Vue2中的配置项用法基本相同
-Vue3.2的优点:
与Vue2相比:
1.组合式api比起配置项更适合代码量庞大的项目,将实现一种功能的代码放在一起,而不是分别放在 data,methods,mounted等不同的配置项中
2.组合式api更适合自定义Hooks
3.全面拥抱TS
4.支持tsx//虽然我还不会 与Vue3.0相比:
setup语法糖,无需一个个return//第一次看到Vue3.0就是被繁琐的return劝退了
Typescript入门
TS显式类型-限制类型
const a: number = 1
const b: string ='woaini'
const c: boolean = true
------------------------------------------------
const d = [1,'woaini',true]//任意元素的数组
const e: number[] =[1,2,3]//限制元素类型的数组
const f: Array<number>=[3,4,5]//限制元素类型的数组
-----------------------------------------------------
function test (x: number,y?: string) //?:表示可传参,也可不传
{
if(y)
{
consolie.log(y)
}
或者
console.log(y?.join())
//不确定是否存在y所以必须这样使用
}
联合类型和类型别名和接口
1.联合类型
number | string //称为联合类型
#### 2.类型别名
2.类型别名
type Userid = number | string //此时userId变成一个新类型,类型别名一般大写
function test (x: UserId)
3.接口
interface Point{
x: string;
y: strng ;
}
function test (x: Point)
--接口和类型别名的区别:
1.类型别名定义必须有'='等号,接口不需要
2.接口是可扩展的,类型别名不能重复定义
interface Point{
x: string
}
interface Point{
y: string
}
//等价于
interface Point{
x: string
y: string
}
而
type Point =number
type Point =string
报错,不能出现两个Point
3.接口可以通过extends继承新的成员,而类型别名不可以
4.接口算是一种特殊的抽象类,用来规范类的格式-详情见类
类型断言和文本类型
类型断言:
将不确定的类型在编译时指定为具体的类型
类型断言的两种方式:
1.as:(主要使用as,因为jsx支持as)
const a: any='hello' as string
2.尖括号:
const <string>a: any='hello'
文本类型:
将类型限制成更具体的string,number,boolean中的值
function test (a: 'get' | 'post' |)//只能传入post和get字符串
const a ={
testoption: 'get'//现在是string类型
}
function test (a.testoption as 'get')//更具体
类型缩小:
function test (a: array | string | null)
{
if (typeof a=='object'/'string'/'number'){ }
}
坑:typeof array和null都是'object'
类:
三种访问权限:public private protected且以修饰符的形式使用
与c++不同的是,TS中默认权限为public
class Animal{
name: string
age: number
constructor(name: string,age: number){
this.name=name
this.age=age
}
}
class Cat extends Animal
{
kind: string
constructor(name: string,age: number,kind: string){
super(name,age)//super关键字-指向父类实例的指针,这里调用父类构造函数
this.kind=kind
}
}
-------------------------------------------------------
let cat = new Cat('咪咪',3,'布偶')
重点:
-
构造函数-constructor
-
继承-extends
-
子类中重写父类的属性或方法调用时优先调用子类的,此时想要使用父类的属性或方法使用super关键字(一个指向父类实例的指针)
-
抽象类:无法实例化对象,专门用来被继承的类-abstract关键字
-
抽象函数:abstract关键字,不在子类中书写该函数则会报错,专门用来提示
abstract class Animal{
name: string
age: number
constructor(name: string,age: number){
this.name=name
this.age=age
}
abstract sayHello(){
}
}
- 在类中实现接口:接口算是一种特殊的抽象类,用来规范类的格式
interface animal{
name: stringS
age: number
sayHello() //不写函数体,也不用写构造函数
}
class Animal implements animal{
name: string
age: number
constructor(name: string,age: number){
this.name=name
this.age=age
}
sayHello(){
console.log('hello')
}
}
- 几个重要的修饰符:public private protected static abstract set和get
- 属性存取器:getter和setter 调用时不用调函数,有语法糖
class dog{
private name: string
private age: number
constuctor(name: string,age: number){
this.name=name
this.age=age
}
set name(name: string)
{
this.name=name
}
get name(){
return this.name
}
}
------------------------------------------------
let dog1 = new dog('旺财',3)
console.log(dog1.name)//getter语法糖,不需要调用get方法
dog1.name='大黄' //setter语法糖,不需要调用set方法
泛型:
✅普通的泛型我把它理解为模板类型,普通的泛型很简单,这里不过多赘述了
包括:泛型函数,泛型接口,泛型类
直到出现下面这个东西,我懵了
发现b站和掘金作者有这种用法,但是没有具体说明,官方文档也没有
探索未知的道路
1.21---------------------------------------------------------------------------------------------------------------
今天再次观摩vue3文档时发现了答案,以下摘自vue3官网
仅限类型的 props/emit 声明:
props 和 emits 都可以使用传递字面量类型的纯类型语法做为参数给 defineProps 和 defineEmits 来声明:
const props = defineProps<{
foo: string
bar?: number
}>()
const emit = defineEmits<{
(e: 'change', id: number): void
(e: 'update', value: string): void
}>()
- defineProps 或 defineEmits 只能是要么使用运行时声明,要么使用类型声明。同时使用两种声明方式会导致编译报错。
- 使用类型声明的时候,静态分析会自动生成等效的运行时声明,以消除双重声明的需要并仍然确保正确的运行时行为。
-
- 在开发环境下,编译器会试着从类型来推断对应的运行时验证。例如这里从 foo: string 类型中推断出 foo: String。如果类型是对导入类型的引用,这里的推断结果会是 foo: null (与 any 类型相等),因为编译器没有外部文件的信息。
- 在生产模式下,编译器会生成数组格式的声明来减少打包体积 (这里的 props 会被编译成 ['foo', 'bar'])。
-
- 生成的代码仍然是有着类型的 Typescript 代码,它会在后续的流程中被其它工具处理。
- 截至目前,类型声明参数必须是以下内容之一,以确保正确的静态分析:现在还不支持复杂的类型和从其它文件进行类型导入。理论上来说,将来是可能实现类型导入的。
-
- 类型字面量
- 在同一文件中的接口或类型字面量的引用
使用类型声明时的默认 props 值
仅限类型的 defineProps 声明的不足之处在于,它没有可以给 props 提供默认值的方式。为了解决这个问题,提供了 withDefaults 编译器宏:
interface Props {
msg?: string
labels?: string[]
}
const props = withDefaults(defineProps<Props>(), {
msg: 'hello',
labels: () => ['one', 'two']
})
上面代码会被编译为等价的运行时 props 的 default 选项。此外,withDefaults 辅助函数提供了对默认值的类型检查,并确保返回的 props 的类型删除了已声明默认值的属性的可选标志。
尾言:
这是Yang学习前端的第二个月了,Yang的前端之路才刚刚开始,希望几年后的Yang能感谢今天自己的坚持
共勉