赞
踩
Object.defineProperty
实现响应式指令编译
的基础原理observe/watcher/dep
具体指的是什么发布订阅模式
以及其解决的具体问题一旦数据发生变化,我们可以立刻知道,并且做一些你想完成的事情,这些事情包括但不限于以下:
在Javascript里实现数据响应式一般有俩种方案,分别对应着vue2.x 和 vue3.x使用的方式,他们分别是:
对象属性拦截 (vue2.x)
Object.defineProperty
对象整体代理 (vue3.x)
Proxy
其中对象属性拦截,是我们本次课程关注的重点,不管使用其中的哪种方式,道理都是相通的
Object.defineProperty
方法和Proxy对象代理
binding
1.数据更新之后实际上需要执行的代码是什么?
node.innerText = data[dataProp]
为了保存当前的node和dataProp,我们再次设计一个函数执行利用闭包函数将每一次编译函数执行时候的node和dataProp都缓存下来,所以每一次数据变化之后执行的是这样的一个更新函数
() => {
node.innerText = data[dataProp]
}
2.一个响应式数据可能会有多个视图部分都需要依赖,也就是响应式数据变化之后,需要执行的更新函数可能不止一个,如下面的代码所示,name属性有俩个div元素都使用了它,所以当name变化之后,俩个div节点都需要得到更新,那属性和更新函数之间应该是一个一对多的关系
<div id="app">
<div v-text="name"></div>
<div v-text="name"></div>
<p v-text="age"></p>
<p v-text="age"></p>
</div>
<script>
let data = {
name: 'cp',
age: 18
}
</script>
经过分析我们可以得到下面的存储架构图,每一个响应式属性都绑定了相对应的更新函数,是一个一对多的关系,数据发生变化之后,只会再次执行和自己绑定的更新函数
理解发布订阅,关键是理解
一对多
dom绑定事件的方式,我们学过俩种
这俩种绑定方式的区别是,第二种方案可以实现同一个事件绑定多个回调函数,很明显这是一个一对多的场景,既然浏览器也叫作事件,我们试着分析下浏览器事件绑定实现的思路
首先addEventListenr是一个函数方法,接受俩个参数,分别是事件类型
和回调函数
因为是一个事件绑定多个回调函数,那在内存里大概会有这样的一个数据结构
{
click: ['cb1','cb2',....],
input: ['cb1','cb2',...]
}
触发事件执行,浏览器因为有鼠标键盘输入可以触发事件,大概的思路是通过事件名称找到与之关联的回调函数列表,然后遍历执行一遍即可
ok,我们分析了浏览器事件的底层实现思路,那我们完全可以自己模仿一个出来,事件的触发,我们也通过设计一个方法来执行
// 增加dep对象 用来收集依赖和触发依赖 const dep = { map: Object.create(null), // 收集 collect(dataProp, updateFn) { if (!this.map[dataProp]) { this.map[dataProp] = [] } this.map[dataProp].push(updateFn) }, // 触发 trigger(dataProp) { this.map[dataProp] && this.map[dataProp].forEach(updateFn => { updateFn() })
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。