🗒️vue3源码学习-3-实现reactivity
2022-5-27
| 2024-3-22
0  |  阅读时长 0 分钟
date
icon
password
description
permalink
categories
type
status
slug
summary
tags
category
updated
Mar 22, 2024 09:10 AM

前言

经过前面的环境搭建以及项目构建,完成了基础的项目框架,下面学习实现vue3的reactivity。

观察官方如何使用

首先修改.npmrc文件
我们在vue3-plan上安装vue3
这个时候发现node_moules中vue的依赖被展开了放在根目录上,在packages/reactivity/index.html上引入vue官方的reactivity
通过上面的实验观察发现通过reactive包裹之后的对象,能被监听到变化,然后effect通过监听到变化而触发回调函数,从而打印出上面到语句。并且reactive是能深层检测到对象的改变,当你修改了address里面的num值时也能被监听到变化,这得益于vue3采用到proxyshallowRactiveshallowReadonly如名字,只能监听到表层,以为深处到属性并未做包装。

vue3对比vue2的变化

  • 在Vue2的时候采用defineProperty来进行数据的劫持,需要对属性进行重写gettersetter性能差。
  • 当新增属性和删除属性式就无法监听变化,需要通过$set$delete实现。
  • 数组不采用defineProperty来进行劫持(浪费性能,对所有索引进行劫持会造成性能的浪费)需要对数组单独进行处理。
Vue3使用Proxy来实现响应式数据变化,从而解决上述问题。

编写自己的响应式

首先引入的JS文件的html,从官方的引入链接改成引入自己的链接

为功能划分文件

reactivity/src/下新建effect.tsreactive.ts文件,对应上面html的2个功能。
同时在index.ts中抛出这2个函数
这样html中引入编译好的JS文件就能获取这2个函数了。
  1. 编写reactive功能
    1. 上面定义个了proxy代理对象,但是为啥不能如上图编写。看下面的解析
      经过上面的修改,初步得到了一个代理对象的方法。此时如果用户在使用上面的代码的时候,他是这么写的
      那么实际上这2个应该使用一个对象的,为此我们修改一下上面的代码,增加缓存设置,这里用上了WeakMap。弱链接Map,好处在于key为null自动清空对应映射关系,其二是key只能为对象。修改上面的代码为
      这个时候reactive就有了同一个对象代理多次,返回同一个代理。现在又有个新需求,如果代理再一次被代理,那应该返回代理,而不是代理的代理对象。
      那么怎么让判断为true呢,早期的处理方式是,WeakMap,正方向存一次,反方向存一次就像 target -> proxy proxy -> target 最新的处理方法是定一个枚举变量。当你你传入的是proxy的时候,可以看一下时候代理过,如果有,那么他一定走到了get方法,并且我们访问了ReactiveFlags.IS_RECEIVE,那么就表示这个是被代理过的,就直接返回 target。
       
  • Vue
  • TypeScript
  • 前端实现文件下载Vue项目中配置vuex版本问题错误
    • Waline
    目录