ToC
activeEffect
我们将重新创建一个 effect
函数,用它来实现这个逻辑。
同时将原本的 effect
函数更新:
当然,这项改动也意味着我们不再需要调用 effect
函数,因为它会在我们传递函数的时候调用。
但是我们现在需要更新追踪函数,那这个时候 activeEffect
变量就会派上用场了。回到 track()
函数上:
我们用一个比较高级一点的测试用例来验证这个过程。
通过以上代码我们可以确定现在代码不会再没有 activeEffect
函数的时候执行追踪函数。
ref 的实现
但是光这么做意义还不是很大,为什么我们没有根据销售价格来计算总数呢?比如将 total = product.price * product.quantity
替换为 total = salePrice * product.quantity
。但这并不能正常工作,因为 salePrice
不是响应式的,所以这是使用 ref
的好时机。 ref
接收一个值,并返回一个响应的,可变的 Ref
对象。 Ref
对象只有一个 .value
属性,它指向内部的值,这听起来好像是从一个文件中复制粘贴出来的(hhh)。那我们的代码将会变成这样:
现在我们需要考虑如何定义及实现 ref
。第一种方法我们可以使用上面的 reactive
函数来实现它:
但是 Vue3 中并不是这么做的,因为 reactive 返回的东西可能会包含其他属性,而 ref 应该只包含值。为了学习 Vue3 如何实现 ref,我们需要了解 对象访问器(getter)
是什么,有时也被称之为 计算属性
。但这里指的并不是 Vue3 中的计算属性,而是 JavaScript 中的计算属性。我们先看个例子:
在具备上述知识后,我们去尝试实现它:
我们尝试去使用它:
computed
其实到了这里,你应该早就想到了,为什么我不直接使用 computed
而是使用 effect
来每次都手动维护变量的值呢?说干就干,我们尝试着修改代码:
那么我们尝试去实现之前,我们要知道我们需要做哪些事情:
- 创建一个响应式引用,我们可以叫它
result
- 在
effect
中运行 getter
,因为我们需要监听响应值,然后将 getter
赋值于 result.value
- 最后我们返回
result
好的,那么我们去实现它:
是的,就这么简单,我们将其应用起来,其最终结果应该与之前一致的,只不过在使用的时候需要增加 .value
属性,就像这样:
当然得意于 Proxy
的能力,使得我们可以做到在 Vue2
中做不到的事情:为一个没有声明初始值的变量添加响应式。比如说这样:
完整代码
截止到这里,完整代码如下:
以上。