let box = ref(null)
onMounted(()=>{
console.log(box.value); //获取到dom值
})
return {box}
}
实现
function ref(val) {
reactive({value:val})
}
递归监听
把每一层都包装成proxy对象,当数据量很大的时候,很耗性能
非递归监听(只有在监听数据量比较大的时候 )
shallowReactive只会监听第一层,如果第一层没变,则不会更新UI界面,
shallowRef 本质也是shallowReactive({value:}),所以value也是他的第一层
shallowReactive实现
function shallowReactive(obj){
return new Proxy(obj,{
get(obj,key){
return obj[key]
},
set(obj,key,value){
obj[key] = value
console.log(‘更新UI界面’);
return true //如果obj是数组的的话,它会改变两次,一次是value,一次是length ,不然会报错
}
})
}
shallowRef的实现
function shallowRef(val) {
shallowReactive({value:val})
}
所以需要改变它第一层value的数据,才会更新页面,或者是通过triggerRef主动触发,只提供triggerRef,没提供triggerReactive
state.value.a.b = 1
triggerRef(state),
只有通过ref或者reactive包装之后的对象修改才会更新UI
1.通过原始数据的不会
let obj = {a:1}
let state = reactive(obj)
obj.a = 2
//state.a = 2 obj.a = 2
虽然数据改了,但是ui界面不会同步更新
2.或者通过toRaw获取到的原始数据修改也不会更新UI
let state = ref(2)//ref本质是reactive({value:})
let state1 = toRaw(state.value)
state1.a = 3
3.通过markRaw(),不让数据被追踪,所以之后修改了数据,UI也不会更新
let obj = {a:1}
obj = markRaw(obj)
let state = reactive(obj)
应用场景:
当UI界面不需要更新的时候,因为每次修改UI界面更新其实是挺消耗性能的,这样可以减少重绘回流的次数
ref
let obj = {a:1}
let state = ref(obj.a)
state.value.a = 3
//state变了,原始obj不变,UI变
toRef
let obj = {a:1}
let state = toRef(obj,‘a’)
state.value.a = 3
//state变,原始obj变,ui不变
**ref => 它的本质是复制,修改不会影响以前的数据,UI会变
toRef => 它的本质是引用,修改会影响到以前的数据,但是,UI不会改变**
toRefs => 跟toRef一样,只是接收参数不一样
let obj = {a:1,b:2}
let state = toRefs(obj,‘a’,‘b’) //等于 let state = toRefs(obj)
state.a.value = 3
state.b.value = 3
应用场景: 如果想让响应式数据和原始数据关联起来,并且更新之后不想更新到UI,则可以使用
返回一个ref对象,可以显式的控制依赖追踪和触发相应
function myRef(value) {
return customRef((track,trigger)=>{
return {
get(){
track();//告诉VUE 这里的数据是需要追踪的
return value
},
set(newValue){
value = newValue
trigger()//告诉vue触发页面更新
}
}
})
}
用于创建一个只读的数据,它是递归只读
let state = readOnly({age:1,attr:{age:1}})
结束
一次完整的面试流程就是这样啦,小编综合了腾讯的面试题做了一份前端面试题PDF文档,里面有面试题的详细解析,分享给小伙伴们,有没有需要的小伙伴们都去领取!