• Vue3源码系列之reactiveApi实现


    • reactive    可以将一个对象编程响应式的,不管有多少层
     
    • shallowReactive   可以将一个对象编程响应式的,只管第一层
     
    • readonly   属性不能去更改,只能读,多少层都不能改
     
    • shallowReadonly    既能读还只关系第一层,除了第一层,其它随便改
     
    核心方法
    第一步:
    注:
    • 根据传参不同,实现不同的功能,为reactive 、shallowReactive 、readonly  、shallowReadonly提供基础功能,这四个api通过传参不同实现各自的功能
    • 第一个参数是这个目标,是否仅读,每个方法的handlers
     
    第二步:
    写个方法判断是否是对象,因为target如果不是对象就没法拦截了,reactive这个api只能拦截对象类型
     
    如果target不是对象就返回target本身
     
    第三步
    判断这个对象是否已经被代理过了,如果某个对象已经被代理过了,就不要再次代理了,直接返回上次代理过的结果
     
    这时候出现一个问题,可能一个对象,被深度代理,同时又被仅读代理了。
     
    创建两个空间去分别缓存一个是纯响应的,一个是只读的
     
    然后去判断传入的第二个参数,判断当前是处理仅读的还是响应的
     
    第四步
    用proxy去完成代理工作,代理完之后将要代理的对象和对应代理的结果缓存起来
     
     然后下次进来去缓存中查找,如果缓存中存在,就取出返回出去
     
    第五步
    将四种api的handlers抽离出去
    新建个文件baseHandlers.ts
     
    第六步
    编写4个handlers的基础get方法 - createGetter
     
    仅读的不会有set方法,所以直接报错
     
    第七步
    再写个合并方法
     
     
    将这两个只读的get方法抽离出来,合并进各自的handlers里
     
    第八步
    为纯响应的两个api专门写set方法
     
    然后放入各自的handlers里
     
    第九步
    上述步骤基本架子已答好,现在只需要专门写get和set的基础方法即可
     
    createGetter:
    第一个参数是代理源对象,属性名称,代理对象本身
     
     
    取值并返回
     
    设置值也是一样
     
    Reflect方法介绍一下:
    • es6语法
    • 后续Object上的方法,会被迁移到Reflect上
    • 以前target[key] = value 方式设置值可能会失败,因为有些属性可能是只读的,这种情况下并不会报异常,也没有返回值表示,而Reflect会把设置成功与否的状态返回回来,boolean类型,也就是Reflect具备返回值
     
    第十步
    createGetter方法里
    • 如果判断不是仅读的,要收集依赖,等会数据变化后更新对应的视图
    • 判断如果是浅的就直接返回
    • 如果res是对象,就要考虑一下是不是仅读的,就处理成仅读的,否则处理成响应式
    注:这里就跟vue2不一样了,vue2是一上来就递归,vue3是当取值时会进行代理,vue3的代理模式是懒代理
     
     
     
    博主掘金技术社区地址——https://juejin.cn/user/1908407918660871/posts
  • 相关阅读:
    ssh-copy-id 的使用方法
    如何保证 docker daemon重启,但容器不重启
    vim设置golang语法高亮 (Centos)
    Error response from daemon: Error running DeviceCreate (createSnapDevice) dm_task_run failed
    Please supply the message using either -m or -F option.
    sudo: Sorry, you must have a tty to run sudo Error on a Linux and Unix
    vim plugins (vim 插件) 工具集
    OmniGraffle v6 注册码
    test
    Collections.addAll 为什么比collection.addall 快(转)
  • 原文地址:https://www.cnblogs.com/tengfeiS/p/15250248.html
Copyright © 2020-2023  润新知