VUE3响应式数据的原理
Proxy+Reflect
const user={
name:'x',
child:{
name:'z'
}
}
const proxyUser=new Proxy(user,{
get(target,prop){
console.log('get');
return Reflect.get(target,prop)
},
set(target,prop,val){
return Reflect.set(target,prop,val)
},
deleteProperty(target,prop){
return Reflect.deleteProperty(target,prop)
}
})
VUE3的生命周期
beforeCreate —>setup() created —>setup() beforeMount —>onBeforeMount mounted —>onMounted beforeUpdate —>onBeforeUpdate updated —>onUpdated beforeDestory —>onBeforeUnmount destoryed —>onUnmouted
组合式API
setup 在beforeCreate 之前执行一次,此时组件对象还没有创建,this 为undefined ,一般返回值为为模板提供的数据
注:methods中可以访问setup提供的属性和方法,但在setup中不能访问data和methods方法
setup(props,context)/setup(props,{attrs,slots.emit}) 参数:
- props:包含props配置声明且传入所有属性的对象
- attrs:包含没有在props配置中声明的属性对象,相当于this.$attrs
- slots:包含所有传入的插槽内容的对象,相当于this.$slot
- emit:用来分发自定义事件的函数,相当于this.$emit
export default{
setup(props,context){
let res=[]
return {
res
}
}
}
ref 创建一个响应式引用
import {ref} from 'vue'
export default{
setup(props,context){
let res=ref([])
return {
res
}
}
}
reactive 用于定义多个数据的响应式
import reactive from 'vue'
const proxy=reactive(obj)
ref和reactive细节:
- ref用于处理基本数据类型,reactive用于处理对象
- ref通过给value属性添加getter/setter来实现对数据的劫持
- reactive通过使用Proxy实现对对象内部所有数据的劫持,并通过Reflect操作对象内部的数据
- ref获取值在js中需要添加.value,在模板中不需要
- 计算属性与监视
(1)computed 接收一个getter函数,并返回一个不可变的响应式ref对象
const count=ref(1)
const fn=computed(()=>count.value+1)
或者接收一个具有get和set的对象,用来创建可写的ref
const count=ref(1)
const fn=computed(()=>{
get:()=count.value+1,
set:val=>count.value=val-1
})
(2)watchEffect 立即执行传入的函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数
(3)watch 初始时不执行回调,如果需要执行需配置immediate 为true ,可以监视一个或多个响应式数据,一旦数据发送变化,就自动执行监视回调,通过配置deep 为true 来指定深度监视
watch(user,(value)->{
console.log(value)
},{
immediate:true,
deep:true
})
watch([()=>user.name,fullname],(values)=>{
})
- toRefs
把一个响应式对象转换成普通对象,该普通对象的每个property都是一个ref
应用场景:比如对reactive用扩展运算符展开的属性是不具有响应式的,因此要使用toRefs
ref还可以用于获取元素
<input ref='inputRef'>
const inputRef=ref(null)
<input ref='inputRef' v-for='item in data'>
const inputRef=ref(new Map())
- toRaw和markRaw
toRaw :返回由reactive或readonly方法转换成响应式的普通对象,访问时不会被代理,写入时也不会触发界面更新 markRaw:标记一个对象使其永远不会转换为代理 - toRef
为源响应式对象创建一个Ref对象,更新时两者是同步的,而ref更新时相互不影响 - customRef
自定义响应式的依赖跟踪和触发更新
customRef((track,trigger)=>{
return{
get(){
track(){}
}
set(){
trigger(){}
}
}
})
- provide和inject
主要用于实现跨层级通信
provide(属性名,属性值)
inject(属性名)
- 响应式数据的判断
isRef :检查一个值是否为ref对象isReactive :检查一个对象是否是由reactive创建的代理isReadonly :检查一个对象是否由readonly创建的只读代理isProxy :检查一个对象是否由reactive或readonly方法创建的代理
- 新组件
(1)Fragment 在vue2中组件必须有一个根标签,vue3中可以没有根标签,内部会将多个标签包含在一个Fragment虚拟元素中 (2)Teleport 可以将组件移动到App之外的其他位置 (3)Suspense 等待异步组件时渲染一些额外内容,优化用户体验
- 其他
(1)v-if 优先v-for 解析 (2).sync 修改符已移除, 由v-model 代替
|