Vue.js 设计与实现
霍春阳(HcySunYang)
Vue.js 官方团队成员
340 人已学习
立即订阅
Vue.js 设计与实现
15
15
1.0x
00:00/00:00
登录|注册

第 5 章 非原始值的响应式方案(3)

5.8 代理 SetMap

从本节开始,我们将介绍集合类型数据的响应式方案。集合类型包括 Map/Set 以及 WeakMap/WeakSet。使用 Proxy 代理集合类型的数据不同于代理普通对象,因为集合类型数据的操作与普通对象存在很大的不同。下面总结了 SetMap 这两个数据类型的原型属性和方法。
Set 类型的原型属性和方法如下。
size:返回集合中元素的数量。
add(value):向集合中添加给定的值。
clear():清空集合。
delete(value):从集合中删除给定的值。
has(value):判断集合中是否存在给定的值。
keys():返回一个迭代器对象。可用于 for...of 循环,迭代器对象产生的值为集合中的元素值。
values():对于 Set 集合类型来说,keys()values() 等价。
entries():返回一个迭代器对象。迭代过程中为集合中的每一个元素产生一个数组值 [value, value]
forEach(callback[, thisArg])forEach 函数会遍历集合中的所有元素,并对每一个元素调用 callback 函数。forEach 函数接收可选的第二个参数 thisArg,用于指定 callback 函数执行时的 this 值。
Map 类型的原型属性和方法如下。
size:返回 Map 数据中的键值对数量。
clear():清空 Map
delete(key):删除指定 key 的键值对。
has(key):判断 Map 中是否存在指定 key 的键值对。
get(key):读取指定 key 对应的值。
set(key, value):为 Map 设置新的键值对。
keys():返回一个迭代器对象。迭代过程中会产生键值对的 key 值。
values():返回一个迭代器对象。迭代过程中会产生键值对的 value 值。
entries():返回一个迭代器对象。迭代过程中会产生由 [key, value] 组成的数组值。
forEach(callback[, thisArg])forEach 函数会遍历 Map 数据的所有键值对,并对每一个键值对调用 callback 函数。forEach 函数接收可选的第二个参数 thisArg,用于指定 callback 函数执行时的 this 值。
观察上述列表可以发现,MapSet 这两个数据类型的操作方法相似。它们之间最大的不同体现在,Set 类型使用 add(value) 方法添加元素,而 Map 类型使用 set(key, value) 方法设置键值对,并且 Map 类型可以使用 get(key) 方法读取相应的值。既然两者如此相似,那么是不是意味着我们可以用相同的处理办法来实现对它们的代理呢?没错,接下来,我们就深入探讨如何实现对 SetMap 类型数据的代理。

5.8.1 如何代理 SetMap

前文讲到,SetMap 类型的数据有特定的属性和方法用来操作自身。这一点与普通对象不同,如下面的代码所示:
// 普通对象的读取和设置操作
const obj = { foo: 1 }
obj.foo // 读取属性
obj.foo = 2 // 设置属性
// 用 get/set 方法操作 Map 数据
const map = new Map()
map.set(‘key’, 1) // 设置数据
map.get(‘key’) // 读取数据
正是因为这些差异的存在,我们不能像代理普通对象那样代理 SetMap 类型的数据。但整体思路不变,即当读取操作发生时,应该调用 track 函数建立响应联系;当设置操作发生时,应该调用 trigger 函数触发响应,例如:
const proxy = reactive(new Map([['key', 1]]))
effect(() => {
console.log(proxy.get(‘key’)) // 读取键为 key 的值
})
proxy.set(‘key’, 2) // 修改键为 key 的值,应该触发响应
当然,这段代码展示的效果是我们最终要实现的目标。但在动手实现之前,我们有必要先了解关于使用 Proxy 代理 SetMap 类型数据的注意事项。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了使用代理(Proxy)实现对集合类型数据的响应式方案。通过具体的代码示例和讲解,读者可以了解如何使用代理实现对集合类型数据的响应式方案,并获得实用的技术指导。文章首先列举了Set和Map类型的原型属性和方法,然后讨论了代理Set和Map类型数据的注意事项,包括解决代理对象的this指向问题。通过使用代理对象的get拦截函数,可以指定访问器属性size的getter函数执行时的this指向,解决了代理Set和Map类型数据时可能遇到的问题。文章还详细讲解了为Set类型数据创建代理时的注意事项,并展示了如何建立响应联系和触发响应。最后,文章对代码进行了优化,提高了性能友好性。整体而言,本文通过深入的技术讲解和丰富的示例,为读者呈现了一种高效的集合类型数据响应式方案。文章内容涵盖了代理对象的使用、响应式方案的实现细节以及性能优化,对于想要深入了解JavaScript集合类型数据响应式方案的读者来说,是一篇非常有价值的技术文章。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Vue.js 设计与实现》
立即购买
登录 后留言

精选留言

由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。
收起评论
显示
设置
留言
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部