四、实现简易 Computed 方法

用过 Vue 的同学可能会好奇,上面的 salePrice 和 total 变量为什么不使用 computed 方法呢?

没错,这个可以的,接下来一起实现个简单的 computed 方法。

const computed = getter => {
    let result = ref();
    effect(() => result.value = getter());
    return result;
}

let product = reactive({ price: 10, quantity: 2 });
let salePrice = computed(() => {
    return product.price * 0.9;
})
let total = computed(() => {
    return salePrice.value * product.quantity;
})

console.log(total.value, salePrice.value);
product.quantity = 5;
console.log(total.value, salePrice.value);
product.price = 20;
console.log(total.value, salePrice.value);

这里我们将一个函数作为参数传入 computed 方法,computed 方法内通过 ref 方法构建一个 ref 对象,然后通过 effct 方法,将 getter 方法返回值作为 computed 方法的返回值。

这样我们实现了个简单的 computed 方法,执行效果和前面一样。

五、源码学习建议

1. 构建 reactivity.cjs.js

这一节介绍如何去从 Vue 3 仓库打包一个 Reactivity 包来学习和使用。

准备流程如下:

  1.  Vue 3 仓库下载最新 Vue3 源码;
1git clone https://github.com/vuejs/vue-next.git
  1. 安装依赖:
1yarn install
  1. 构建 Reactivity 代码:
1yarn build reactivity
  1. 复制 reactivity.cjs.js 到你的学习 demo 目录:

上一步构建完的内容,会保存在 packages/reactivity/dist目录下,我们只要在自己的学习 demo 中引入该目录的 reactivity.cjs.js 文件即可。

  1. 学习 demo 中引入:
1const { reactive, computed, effect } = require("./reactivity.cjs.js");

2. Vue3 Reactivity 文件目录

在源码的 packages/reactivity/src目录下,有以下几个主要文件:

  1. effect.ts:用来定义 effect / track / trigger ;
  2. baseHandlers.ts:定义 Proxy 处理器( get 和 set);
  3. reactive.ts:定义 reactive 方法并创建 ES6 Proxy;
  4. ref.ts:定义 reactive 的 ref 使用的对象访问器;
  5. computed.ts:定义计算属性的方法;

vue3的响应式原理(四)_Vue