Vue3
前置
名称:onePiece
拥抱ts
一.创建vue3.0工程
1.使用vue.cil创建
终端命令行输入vue create 加项目名
2.使用vite创建
vite是新一代的前端构建工具
优势:无需打包,直接可以启动
真正的按需编译,不再等待整个应用编译完成
二.常用的CompositionAPI
1.拉开序幕的setup
1.理解:vue3中的一个全新的配置项,值是一个函数
2.setup时所有Composition API
3.组件中所用到的:数据方法,都要配置在setup中
4.setup函数的两种返回值:
1.若返回一个对象,则对象中的属性,方法,在模版中均可以直接使用(重点)
2.若返回一个渲染函数,则可以自定义渲染内容
5.注意点:
1.尽量不要和vue2混用
setup中不能访问vue2配置
vue2可以访问setup中的方法
2.setup不能是一个async函数,因为返回值不是return的对象,而是promise,模版中看不到return对象中的属性
2.ref函数
1.作用:定义一个响应式数据
2.语法:const xxx = ref(数据)
1.创建一个包含响应式数据的应用对象
2.js中操作数据:xxx.value
3.模版中读取数据:不需要value
3.注:
1.接收数据可以是:基本类型,也可以是对象类型
2.基本类型的数据:响应式依然是靠object.defineProperty()的get和set方法完成的
3.对象类型的数据:内部‘求助了’v3中的一个新函数-reactive函数
3.reactive函数
1.作用:定义一个对象类型的响应式数据(基本类型不要用他,用ref函数)
2.语法:const 代理对象 = reactive(源对象) 接收一个对象(或数组),返回一个代理对象(proxy对象)
3.reactive定义的响应式数据是“深层次的”
4.内部基于es6的proxy实现,通过代理对象操作元对象内部数据进行操作
4.Vue3中响应式的原理
1.vue2的响应式原理
原理:
1.对象类型:通过object.defineProperety()对属性的读取,修改进行拦截(数据劫持)
2.数组类型:通过重写更新数组的一系列方法来实现拦截
2.vue3的响应式原理

原理:
1.通过proxy:拦截对象中任意属性的变化,
2.通过reflect:对被代理对象的属性进行操作

5.ref和reactive对比
1.从定义数据的角度出发
1.ref用来定义:基本数据类型
2.reactive:对象数据类型
注:ref也可以用来定义对象或数组类型数据,内部会通过reactive转为代理对象
2.从原理角度对比
1.ref通过obj.defineproperty()的get和set来实现相应式(数据劫)
2.reactive通过使用proxy来实现响应式,并通过reflect操作源对象内部的数据
3.从使用角度对比
1.ref定义的数据:操作数据需要value,读取数据时模版中直接读取不需要value
2.reactive定义的数据:操作数据与读取数据均不需要value
6.setup的两个注意点
1.setup执行的时机
在beforeCreate之前执行一次,this.是undefined
2.setup的参数
1.props:值为对象,包含:组件外部传递过来的,且组件内部声明接收了的属性
2.context:上下文对象
1.attrs:值为对象,包含组件外部传递过来的但是没有在props配置中声明的属性
2.slots:收到的插槽内容,相当于this.$solts
3.emit:分发自定义事件的函数,相当于this.$emit
7.计算属性与监视
1.computed函数
功能一致但是需要引入
//计算属性-简略写法
Person.fullName = computed(()=>{
return Person.firstName + '-' + Person.lastName
})
//计算属性-完整写法
Person.fullName = computed({
get(){
return Person.firstName + '-' + Person.lastName
},
set(value){
const nameArr = value.split('-')
Person.firstName = nameArr[0]
Person.lastName = nameArr[1]
}
}
2.watch函数
//情况1监视ref所定义的响应式数据
watch(sum,(newValue,oldValue)=>{
console.log('sum变了',newValue,oldValue);
},{immediate:true})
//情况2监视ref所定义的多个响应式数据
watch([sum,msg],(newValue,oldValue)=>{
console.log('sum或msg变了',newValue,oldValue);
},{immediate:true})
//情况三监视reactive所在的对象内容
// 注意
// 1.此处无法正确的获取一个oldValue
// 2.强制开启了深度监视
watch(person,(newValue,oldValue)=>{
})
//情况四:监视reactive所定义的一个响应式数据中的某个属性
watch(()=>person.age,(newValue)=>{
console.log('age被变了',newValue);
})
//情况五监视reactive所定义的一个响应式数据中的某些属性
watch([()=>person.age,()=>person.name],(newValue)=>{
console.log('name或者age被变了',newValue);
})
//特殊情况
watch(()=>person.job,(newValue)=>{
console.log('name或者age或者salary被变了',newValue);
},{deep:ture})
ref和reactive的区别
watch(sum,(newValue,oldValue)=>{
console.log('sum的值发生变化了')
})
//person.value相当于ref从reactive里面借了proxy方法将person转换为reactive
watch(person.value,(newValue,oldValue)=>{
console.log('person里面的值发生变化了')
})
//
watch(person,(newValue,oldValue)=>{
console.log('person里面的值发生变化了')
},{deep:true})
3.watchEffect函数
watch的套路是:既要指明监视的属性,也要指明监视的回调
watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性
watchEffect有点像computed
1.但是computed注重的计算出来的值,所以要写返回值
2.而watchEffect更注重的是过程,所以不用写返回值
watchEffect(()=>{
const x1 = sum.value
const x2 = person.job.j1.salary
console.log('watchEffect所指定的回调被触发了')
})
8.生命周期
9.自定义hook函数
1.什么是hook
是一个函数,吧setup中使用的composition API进行了封装
类似于vue2中的mixn
2.自定义hook的优势:复用代码,让setup中的逻辑更清楚易懂
10.toRef
1.作用:创建一个ref对象,其value值指向另一个对象中的某个属性
2.语法const name = toRef(person,'name')
3.应用:要将响应式对象中的某个属性单独提供给外部使用
4.扩展toRef与toRefs功能一致,但可以批量创建多个ref对象,torres(person)
三.其他CompositionAPI
1.shallowaReactive与shallowRef
1.shallowreactive:只处理对象最外层属性的响应式
2.shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理
什么时候用:
1.如果有一个对象数据,结构比较深,但变化时只是外层属性变化==>shallowReactive
2.如果有一个对象数据,后续功能不会修改该对象中的属性,而是新的对象来替换===>shallowRef
2.readonly与shallowReadonly
1.readonly:让一个响应式数据变为只读
2.shallowReadonly:让一个响应式数据变为只读的(浅只读),第一层不可改,深层次可以改
3.应用场景,不希望数据被修改
3.toRaw与markRaw
1.toRaw:
1.作用:将一个reactive生成的响应式对象转为普通对象(只能处理reactive类型的)
2.使用场景:用于读取响应式对象对应的普通对象,对于这个普通对象的所有操作,不会引起页面更新
2.markRaw
1.作用:标记一个对象,使其永远不会再成为响应式数据
2.使用场景:
1.有些值不应该被设置成响应式的
2.当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能
4.customRef
1.作用:创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显示控制
经典案例
<template>
<input type="text" v-model="keyWord">
<h3>{{keyWord}}</h3>
</template>
<script>
import {ref,customRef} from 'vue'
export default {
name: 'App',
setup(){
//自定义一个ref
function myRef(value,time){
let timer
return customRef((track,trigger)=>{
return {
get(){
console.log(`有人从myRef中读取了数据,吧${value}给他了`)
track()//通知cue追踪value的变化(提前和get商量一下,让他认为这个value是有用的)
return value
},
set(newValue){
console.log(`有人从myRef中的数据改了,${newValue}`)
clearTimeout(timer)
timer = setTimeout(()=>{
value = newValue
trigger()//通知vue去重新解析模版
},time)
}
}
})
}
// let keyWord = ref('hello')//使用vue提供的ref
//使用程序员自定义的ref
let keyWord = myRef('hello',500)
return{keyWord}
}
}
</script>
5.provide与inject
1.作用:实现祖孙组件间的通讯(跨级组件)
2.套路:父组件有一个provide选项来提供数据,子组件有一个inject选项来开始使用这些数据
6.响应式数据的判断
1.isRef:检查一个值是否为对象
2.isReactive:检查一个值是否由reactive创建的响应式代理
3.isReadonly:检查一个对象是否由readonly创建的只读代理
4.isproxy:检查一个对象是否由reactive或者由readonly方法创建的代理
四.Composition API的优势
1.OpitionsAPI存在的问题
使用传统的OpitionsAPI中,新增或者修改一个需求,就需要分别在data,methods,components里面修改
2.CompositionAPI的优势
可以更加优雅的组织我们的代码,函数.让相关功能的代码更加有序的组织在一起
五.新的组件
1.Fragment
v2中必须要有根标签
v3中可以没有根标签,内部会有多个标签包含在一个fragment虚拟元素中
好处:减少标签层,减少内存占用
2.Teleport
什么事Teleport,是一种能够将我们的组件html结构移动到指定位置的技术
3.Suspense
等待异步组件时渲染一些额外的内容,让应用有更好的用户体验