网络网站建,湖北城乡和建设官方网站,苏州模板做网站,鸿星尔克网络推广方案该文章是在学习 小满vue3 课程的随堂记录示例均采用 script setup#xff0c;且包含 typescript 的基础用法 前言
本篇主要学习几个 api 及相关源码#xff1a;
toReftoRefstoRaw
一、toRef
toRef(reactiveObj, key) 接收两个参数#xff0c;第一个是 响应式对象… 该文章是在学习 小满vue3 课程的随堂记录示例均采用 script setup且包含 typescript 的基础用法 前言
本篇主要学习几个 api 及相关源码
toReftoRefstoRaw
一、toRef
toRef(reactiveObj, key) 接收两个参数第一个是 响应式对象第二个是 指定的key作用将 响应式对象 的 一部分也变为响应式通过 .value 修改 toRef 对 非响应式 对象无能为力修改后 视图不会更新若 直接解构 reactiveObj不使用 toRef会使解构出的值 丧失响应式应用场景某个单独的 属性key 需要被单独使用并 希望它是响应式的
① 对非响应式对象无能为力
div classhobby{{ hobby }}/div
button clickchange修改/button// 普通对象
const man {name: xiaoman,age: 18,hobby: ball,
};
const hobby toRef(man, hobby); // 对普通对象使用修改后仅修改值 但不更新视图const change () {hobby.value sing;console.log(hobby, hobby); // Refsing但视图不更新
};打印更新
视图不更新 ② 将响应式对象的一部分也变为响应式
div classhobby2{{ hobby2 }}/div
button clickchange修改/button// reactive 响应式对象
const man2 reactive({name: xiaoman,age: 18,hobby: ball,
});
const hobby2 toRef(man2, hobby);const change () {hobby2.value dance;console.log(hobby2, hobby2, man2) // hobby2 和 man2 都会更新视图也会更新
};打印 视图更新 ③ 直接解构响应式对象
若 直接解构 响应式对象不使用 toRef会使解构出的值 丧失响应式
// reactive 响应式对象
const man2 reactive({name: xiaoman,age: 18,hobby: ball,
});
const { age } man2; // 直接解构会丧失响应式
console.log(直接解构 age------, age);解构出的就只是一个普通的值 二、toRefs
toRefs(reactiveObj) 和 toRef 作用一样只是不再指定某个key而是把全部属性都变为响应式也是需要 传入响应式对象之后若对其解构解构出的也是响应式对象 外层不再是响应式内部的每一个key才是响应式
① 简单实现 toRefs 的源码
其实就是定义一个循环循环体中 调用 toRef
const toRefsCopy T extends object(obj: T) {const map: any {};for (let key in obj) {map[key] toRef(obj[key]);}return map;
};② toRefs 使用
divrefs:{{ refs }}/div
divrefs2:{{ refs2 }}/div
button clickchange2修改/buttonconst blue reactive({name: blue,age: 19,
});const refs toRefsCopy(blue);
const refs2 toRefs(blue);
console.log(refs---, refs, refs2);const change2 () {// 解构出的每一个key都是响应式const { age } refs2;age.value 24;console.log(toRefs, refs, age);
};toRefs 和 toRefsCopy 处理过后每个key都是响应式 直接解构出的 key 也是响应式会立刻更新 三、toRaw
toRaw(reactiveObj) 同样接收一个 响应式对象作用toRaw 使 响应式对象 变为 普通原始对象 取出 响应式对象 中 __v_raw 对应的值跟 toRaw 之后的结果相同__v_raw 是源码内部的操作
const people reactive({name: bill,age: 12,
});// 打印结果people 是具有响应式的对象toRaw 后就变成了普通原始对象
console.log(toRaw-------, people, toRaw(people));// 取出 __v_raw 对应的值跟 toRaw 的结果相同
console.log(__v_raw-------, people[__v_raw]);四、源码学习
源码贴图 源码理解记录
/***reactivity.cjs.prod.js搜索 function toRef 即可找到** 1、function toRef (source, key, defaultValue)* - 先判断 isReftrue的话直接返回* - 再判断是不是函数类型GetterRefImpl 内部仍然是直接返回但会增加一些必要的标记__v_isRef、__v_isReadonly** - 再判断是不是object是的话走进 propertyToRef* - 看 source[key] 是否满足 isRef* true的话直接返回已经设置过响应式了* 否则走进 ObjectRefImpl这就是 toRef 的核心方法* - ObjectRefImpl 与 RefImplref 内部同样有 get、set方法* 但是区别在于 ObjectRefImpl 没有收集依赖(track)、触发更新(trigger) 的操作* 所以 toRef 对普通对象来讲没有响应式只对已经有响应式的对象有用** - 上述类型都不属于的话直接 ref(source)**** 2、function toRefs (object)** - 和上面自己写的 toRefsCopy 思路基本一致* - 先初始化一下[]或者{}* - 然后循环* 判断每个值 若 isReftrue 直接返回* 否则都 走进 ObjectRefImpl 中变为 ref 类型*** 3、function toRaw(observed)** - 判断 observed 是否存在 __v_raw 存在的话继续递归 toRaw否则直接返回 observed* - 取出的结果就是 不带 __v_raw 的原始普通对象***/