# 目录结构

  • vue3 使用了 lerna (opens new window) 这个多包管理器来管理项目里面的各个包,使用 lerna 的好处就是每个包可以单独发布,而不需要所有包一块发布。

  • 现在很多著名的库都会使用 lerna 来管理项目里的包,比如:react、vue3 等等。使用 lerna 来管理的项目里都会有一个 packages 文件夹,整个项目的核心文件都在这个文件夹下。

vue

# 整体架构

vue

vue

# Proxy

vue2 中使用 Object.defineProperty 来劫持对象属性,而 vue3 使用 proxy + reflect 来代理整个对象。使用 proxy 的优缺点如下:

优点

  • 能够代理整个对象,并且能够处理多层属性的响应。之前的 Object.defineProperty 只能做到第一层属性的响应。

  • 能够监听到数组或者对象新增/删除的 key。

  • 支持 13 种拦截操作,功能更强大。

  • 返回新对象而不是直接修改原对象,更符合 immutable。

缺点

  • 兼容性差,目前没有一个完整支持 proxy 所有拦截方法的 polyfill 方案。
function reactive(data) {
  if (typeof data !== "object" || data === null) {
    return data;
  }
  const observed = new Proxy(data, {
    get(target, key, receiver) {
      // Reflect 有返回值不报错
      let result = Reflect.get(target, key, receiver);

      // 多层代理
      return typeof result !== "object" ? result : reactive(result);
    },
    set(target, key, value, receiver) {
      effective();
      // proxy + reflect
      const ret = Reflect.set(target, key, value, receiver);
      return ret;
    },

    deleteProperty(target, key) {
      const ret = Reflect.deleteProperty(target, key);
      return ret;
    }
  });
  return observed;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 模板编译

# 所做的优化

1. 重写 vdom 机制

通过编译时的标记优化运行时的速度。

2. 优化插槽(slot)生成

原来的实现是,父组件重新渲染时子组件也必须同时渲染,而在 vue3 中子组件提取函数,可以分别渲染。

3. 静态树提升

没有响应式绑定的部分被提取出来作为常量,用到的时候不用再次执行它的渲染函数。

4. 静态属性提升

没有响应式绑定的组件属性(props)被提取出来作为常量,用到的时候不用再进行创建。

5. 项目结构优化

内部解耦,更好维护,支持了细粒度的 tree-shaking,比如可选的生命周期。

上次更新时间: 2024年01月05日 23:18:37