云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!
本文仅从理论的角度来阐述Vue.js中的响应式,不涉及具体源码。
Vue.js具有数据响应式的特点。
常见的场景有下面这几个:
- 数据变 → 使用数据的视图变
- 数据变 → 使用数据的计算属性变 → 使用计算属性的视图变
- 数据变 → 开发者主动注册的watch回调函数执行
三个场景,对应三种watcher:
- 负责敦促视图更新的render-watcher
- 执行敦促计算属性更新的computed-watcher
- 用户注册的普通watcher(watch-api或watch属性)
render watcher
结合上面的代码来看,响应式意味着:当name属性值改变时,渲染的内容也应随之变化。
建立联系
如何才能建立视图渲染与属性值之间的联系?先来搞清楚两个问题。
- 谁用了这个数据
- 数据变了之后怎么办
在视图渲染这个场景下,这两个问题的解答分别是:
- 负责生成视图的render函数要用这个数据
- 数据变了得执行render函数
数据劫持
用了和变了,是可以通过对该属性值设置访问描述符(get/set)知道的。
因此,需要遍历所有data属性值,用Object.defineProperty设置访问描述符(get/set)。
- 谁用了这个数据?
触发了属性值get的就是要用到的,应该在getter里记录下使用者。
- 数据变了怎么办?
数据变就会触发属性值set,应该在setter里告知使用者。
订阅-发布
从上面的描述可以看出,这个场景是典型的发布&订阅。
在视图渲染的场景中,render-watcher是订阅者。每个属性值都有一个依赖管理者——dep,负责记录和通知订阅者。
依赖的收集与通知
收集订阅(依赖)者的流程
1.订阅者执行回调(render函数)
2.触发属性值getter
3.添加到订阅者队列
4.重复2、3直至所有getter执行完
通知订阅者的流程
1.属性改变
2.触发属性值setter
3.dep通知订阅者(render watcher)
4.订阅者执行回调(render函数)
取消订阅
当某些属性值不再被视图使用的时候,就应该取消掉对这些属性的订阅。
怎么才能知道哪些属性值不再被引用呢?我们可以这么做:
订阅者(render-watcher)也维护一个依赖集合,将依赖的属性值的dep存储在这个集合里。
每当render function执行一次,也就是触发属性值的getter时,订阅者(render-watcher)会存储一份新的依赖集合。对比新旧依赖集合,找出已经不再依赖的旧dep,将render-watcher从这个旧dep的订阅者队列中删除。这样就不会通知到当前的订阅者了(render-watcher)。
【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/zhibo立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK
原文发布时间:2020-04-14
本文作者:晒了个太阳
本文来自:“掘金”,了解相关信息可以关注“掘金”