第 6 章 原始值的响应式方案
霍春阳(HcySunYang)
在第 5 章中,我们讨论了非原始值的响应式方案,本章我们将讨论原始值的响应式方案。原始值指的是 Boolean、Number、BigInt、String、Symbol、undefined 和 null 等类型的值。在 JavaScript 中,原始值是按值传递的,而非按引用传递。这意味着,如果一个函数接收原始值作为参数,那么形参与实参之间没有引用关系,它们是两个完全独立的值,对形参的修改不会影响实参。另外,JavaScript 中的 Proxy 无法提供对原始值的代理,因此想要将原始值变成响应式数据,就必须对其做一层包裹,也就是我们接下来要介绍的 ref。
6.1 引入 ref 的概念
由于 Proxy 的代理目标必须是非原始值,所以我们没有任何手段拦截对原始值的操作,例如:
对于这个问题,我们能够想到的唯一办法是,使用一个非原始值去“包裹”原始值,例如使用一个对象包裹原始值:
但这样做会导致两个问题:
用户为了创建一个响应式的原始值,不得不顺带创建一个包裹对象;
包裹对象由用户定义,而这意味着不规范。用户可以随意命名,例如 wrapper.value、wrapper.val 都是可以的。
为了解决这两个问题,我们可以封装一个函数,将包裹对象的创建工作都封装到该函数中:
如上面的代码所示,我们把创建 wrapper 对象的工作封装到 ref 函数内部,然后使用 reactive 函数将包裹对象变成响应式数据并返回。这样我们就解决了上述两个问题。运行如下测试代码:
上面这段代码能够按照预期工作。现在是否一切都完美了呢?并不是,接下来我们面临的第一个问题是,如何区分 refVal 到底是原始值的包裹对象,还是一个非原始值的响应式数据,如以下代码所示:
公开
同步至部落
取消
完成
0/2000
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
![](https://static001.geekbang.org/resource/image/d0/e4/d0880927e2a522a038be2d04bf19dfe4.png)
JavaScript中的原始值(Boolean、Number、BigInt、String、Symbol、undefined和null)在响应式方案中的应用是本文的重点。文章介绍了使用Proxy无法直接代理原始值的问题,并提出了通过封装ref函数来解决这一问题的方案。此外,文章还讨论了响应丢失问题,并介绍了使用ref对象下具有与原始对象同名的属性的方式来解决这一问题。最后,文章还介绍了自动脱ref的能力,使得用户在模板中使用响应式数据时无需关心哪些是ref,哪些不是ref。总体而言,本文内容涉及技术点较多,对于想要深入了解原始值的响应式方案的读者具有一定的参考价值。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Vue.js 设计与实现》
《Vue.js 设计与实现》
立即购买
登录 后留言
精选留言
由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。
收起评论