前言(一些闲话,无任何干货,纯瞎bb)
学习前端也有一定的时日了,早有耳闻如果要成为那种万人敬仰的技术大牛,多写博客,多为技术社区贡献是一条必经之路(滑稽),但碍于有拖延症的我来说,这个事情一直没有提上行程,在过年的时候就想着今年一定要写很多很多文章,但是过完年又全给抛脑后了,时至今日却还没产出一篇像样的文章,真是惭愧。或许是突然的开窍,我发现在这么下去就没机会走向人生巅峰了啊可恶,所以在某个阴雨绵绵的下午,开始了自己的第一篇文章。好了闲话说到这里,第一篇就决定是自己从开始学前端开始就一直使用的vue,由于本人比较喜欢举例子和图解,让我用另一种方式来给大家说说我理解的vue数据响应。
一切的基石-Object.defineProperty
同许多mvvm框架相同的是vue让现今的前端感到便利最重要的一点就是数据驱动。
数据驱动:监听数据变化,当发生改变时,视图也会进行对应的更新,举个最简单的例子数据1渲染出了页面1,当改动数据变成2时,原页面就自动渲染成对应的页面2
vue中实现该功能的关键就是 Object.defineProperty这个东西,那么这玩意儿干啥的呢,我这里不详细展开,请各位自行搜索百度谷歌等,说说我认为它的功能:Object.defineProperty:可以为某个对象的属性设置get、set方法,当修改这个属性值的时候会触发刚刚设置好的set方法,当取值的时候就会触发刚刚设置好的get方法
利用它我们就可以实现最简单的数据与页面的绑定。至于实现过程,咳咳~自行百度自行百度,这不是本文重点。。(虽然也是重点),假如你将它了解清楚,至少动手写了写demo,我们继续,接下来就本文的重中之重(敲黑板),如何通过Object.defineProperty构建一套数据响应体系。
数据响应系统的思路
用最简单的流程来表示的话
触发get - 收集依赖 - 监听变化 - 触发set - 取出依赖并执行
这时候有人就要问了依赖是个啥东西,这边你可以把它理解成监听的值发生改变后你想要触发的事件。了解过后我们详细的分解下需要的动作
1.首先,我们需要一个被监听的对象。
2.我们看流程会发现有个收集和取出的动作,所以我们需要一个“袋子”来储存这些东西。
3.我先要将依赖丢入“袋子”中,那么怎么丢呢,监听变化自然要用Object.defineProperty中的set方法,那么剩下的get方法就是我们的目标,具体就是使用取值触发get,从而将依赖入“袋子”
4.使用Object.defineProperty中的是set方法监听变化,一旦触发,就将袋中的依赖一个个取出并执行
用代码实现:
const data = {
a : 1
}; //检测的对象
const bag = []; //"袋子"
let tempEvent = ""; //用于缓存依赖的变量
function $watch (event) {
tempEvent = event; // 将 tempEvent设置为该依赖
data.a; // 读取属性,触发Object.defineProperty的get方法
}
Object.defineProperty(data, 'a', {
set () {
bag.forEach(event => event()) //从袋子中一个个取出并执行
},
get () {
bag.push(tempEvent) // 将上面设置好的依赖入"袋"
}
})
复制代码
于是当我们加入依赖
$watch(() => {
console.log('一个依赖')
})
$watch(() => {
console.log('另一个依赖')
})
复制代码
并且在控制台输入
data.a=1024;
复制代码
就会输出
一个依赖
另一个依赖
复制代码
至此一个最简单的数据响应系统就完成咯,虽然它只能监听一个属性的变化,但是经过后期的不断壮大他也能成为另一个vue,希望自己也能像这串代码一样慢慢不断成长吧,之后我也会继续完善它,感兴趣的同学也可以关注关注,当然要是有大牛能来指出我的一些错误,那就更好不过啦。