vue3 学习笔记
1.reavtive是递归监听实现的,即可以通过obj.a.b直接修改对象,视图会更新,如果数据量大,性能消耗也大。
2.shallowReactive和shallowRef,非递归监听,可以用triggerRef来触发ref的更新。数据量非常大的时候使用。
3.ref本质是reactive({value:"值"})
,所以js访问的时候要加.value,然而渲染的时候会有一个__v_isRef:true
标记,所以模板会直接识别自动加。value,不需要.value
4.vue3响应式数据是靠proxy实现的,读取数据的时候进入get方法,修改数据的时候进入set方法,如下:
1.传入对象时
/*
1.Vue3响应式数据本质
- 在Vue2.x中是通过defineProperty来实现响应式数据的
- 在Vue3.x中是通过Proxy来实现响应式数据的
* */
let obj = {name:'lnj', age:18};
let state = new Proxy(obj, {
get(obj, key){
console.log(obj, key); // { name: 'lnj', age: 18 } name
return obj[key];
},
set(obj, key, value){
console.log(obj, key, value); // { name: 'lnj', age: 18 } name 知播渔
obj[key] = value;
console.log('更新UI界面');
}
});
// console.log(state.name); // lnj
state.name = '知播渔';
console.log(state);
2.传入数组时.set方法必须通过返回值告诉Proxy此次操作是否成功
/*
1.Proxy注意点
- set方法必须通过返回值告诉Proxy此次操作是否成功
* */
// let obj = {name:'lnj', age:18};
let arr = [1, 3, 5]; // [1, 3, 5, 7]
let state = new Proxy(arr, {
get(obj, key){
console.log(obj, key); // [ 1, 3, 5 ] 1
return obj[key];
},
set(obj, key, value){
// [ 1, 3, 5 ] 3 7 先把7放入
// [ 1, 3, 5, 7 ] length 4 在修改他的length
console.log(obj, key, value);
obj[key] = value;
console.log('更新UI界面');
return true;
}
});
// console.log(state[1]);
state.push(7);
手写reactive ref 递归监听
function ref(val){
return reactive({
value:val
})
}
function reactive(obj){
if(typeof obj === "object"){
if(obj instanceof Array){
// 如果是一个数组,那么取出数组的每一个元素,
// 判断每一个元素是否又是一个对象,如果又是,也要包装成一个proxy对象
obj.forEach((item,index) => {
if(typeof item === "object"){
obj[index] = reactive(item)
}
})
}else{
// 如果不是数组是对象,取出对象属性对应的值
// 判断对象属性的取值是否又是一个对象,如果是,包装成proxy对象
for(let key in obj){
let item = obj[key]
if(typeof item === "object"){
obj[key] = reactive(item)
}
}
}
return new Proxy(obj,{
get(obj,key){
return obj[key]
},
set(obj,key,val){
obj[key] = val
console.log('操作dom,更新ui');
return true
}
})
}else{
console.warn(`${obj} is not object!`);
}
}