首页 > 语言 > JavaScript > 正文

Vue响应式原理Observer、Dep、Watcher理解

2024-05-06 15:38:25
字体:
来源:转载
供稿:网友

开篇

最近在学习Vue的源码,看了网上一些大神的博客,看起来感觉还是蛮吃力的。自己记录一下学习的理解,希望能够达到简单易懂,不看源码也能理解的效果😆

Object.defineProperty

相信很多同学或多或少都了解Vue的响应式原理是通过Object.defineProperty实现的。被Object.defineProperty绑定过的对象,会变成「响应式」化。也就是改变这个对象的时候会触发get和set事件。进而触发一些视图更新。举个栗子🌰

function defineReactive (obj, key, val) {  Object.defineProperty(obj, key, {    enumerable: true,    configurable: true,    get: () => {      console.log('我被读了,我要不要做点什么好?');      return val;    },    set: newVal => {      if (val === newVal) {        return;      }      val = newVal;      console.log("数据被改变了,我要把新的值渲染到页面上去!");    }  })}let data = {  text: 'hello world',};// 对data上的text属性进行绑定defineReactive(data, 'text', data.text);console.log(data.text); // 控制台输出 <我被读了,我要不要做点什么好?>data.text = 'hello Vue'; // 控制台输出 <hello Vue && 数据被改变了,我要把新的值渲染到页面上去!>

Observer 「响应式」

Vue中用Observer类来管理上述响应式化Object.defineProperty的过程。我们可以用如下代码来描述,将this.data也就是我们在Vue代码中定义的data属性全部进行「响应式」绑定。

class Observer {  constructor() {    // 响应式绑定数据通过方法   observe(this.data);  }}export function observe (data) {  const keys = Object.keys(data);  for (let i = 0; i < keys.length; i++) {    // 将data中我们定义的每个属性进行响应式绑定    defineReactive(obj, keys[i]);  }}

Dep 「依赖管理」

什么是依赖?

相信没有看过源码或者刚接触Dep这个词的同学都会比较懵。那Dep究竟是用来做什么的呢? 我们通过defineReactive方法将data中的数据进行响应式后,虽然可以监听到数据的变化了,那我们怎么处理通知视图就更新呢?

Dep就是帮我们收集【究竟要通知到哪里的】。比如下面的代码案例,我们发现,虽然data中有text和message属性,但是只有message被渲染到页面上,至于text无论怎么变化都影响不到视图的展示,因此我们仅仅对message进行收集即可,可以避免一些无用的工作。

那这个时候message的Dep就收集到了一个依赖,这个依赖就是用来管理data中message变化的。

<div>  <p>{{message}}</p></div>
data: {  text: 'hello world',  message: 'hello vue',}

当使用watch属性时,也就是开发者自定义的监听某个data中属性的变化。比如监听message的变化,message变化时我们就要通知到watch这个钩子,让它去执行回调函数。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选