四、实现简易 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 包来学习和使用。
准备流程如下:
- 从 Vue 3 仓库下载最新 Vue3 源码;
1git clone https://github.com/vuejs/vue-next.git
- 安装依赖:
1yarn install
- 构建 Reactivity 代码:
1yarn build reactivity
- 复制 reactivity.cjs.js 到你的学习 demo 目录:
上一步构建完的内容,会保存在 packages/reactivity/dist
目录下,我们只要在自己的学习 demo 中引入该目录的 reactivity.cjs.js 文件即可。
- 学习 demo 中引入:
1const { reactive, computed, effect } = require("./reactivity.cjs.js");
2. Vue3 Reactivity 文件目录
在源码的 packages/reactivity/src
目录下,有以下几个主要文件:
- effect.ts:用来定义
effect
/track
/trigger
; - baseHandlers.ts:定义 Proxy 处理器( get 和 set);
- reactive.ts:定义
reactive
方法并创建 ES6 Proxy; - ref.ts:定义 reactive 的 ref 使用的对象访问器;
- computed.ts:定义计算属性的方法;