简单实现Vue的observer和watcher

首先,要实现Vue的Observer和Watcher,需要进行以下步骤:

  1. Observer:

Vue中的Observer实现了数据响应式,它可以监听数据的变化并自动更新相应的视图。实现Observer需要使用ES6的Proxy对象来劫持对象或数组的访问。代码示例:

function observe(obj) {
  if(!obj || typeof obj !== 'object') {
    return;
  }
  Object.keys(obj).forEach((key) => {
    defineReactive(obj, key, obj[key]);
  });
}

function defineReactive(obj, key, val) {
  observe(val); // 递归处理
  const dep = new Dep();
  Object.defineProperty(obj, key, {
    enumerable: true,
    configurable: true,
    get: function reactiveGetter() {
      dep.depend();
      return val;
    },
    set: function reactiveSetter(newVal) {
      if(val === newVal) {
        return;
      }
      val = newVal;
      observe(newVal);
      dep.notify();
    }
  });
}

class Dep {
  constructor() {
    this.subs = [];
  }

  addSub(sub) {
    this.subs.push(sub);
  }

  removeSub(sub) {
    remove(this.subs, sub);
  }

  depend() {
    if(window.target) {
      this.addSub(window.target);
    }
  }

  notify() {
    const subs = this.subs.slice();
    for(let i = 0, l = subs.length; i < l; i++) {
      subs[i].update();
    }
  }
}

function remove(arr, item) {
  if(arr.length) {
    const index = arr.indexOf(item);
    if(index > -1) {
      return arr.splice(index, 1);
    }
  }
}

在这段代码中,我们使用Object.defineProperty方法重写所需要劫持的对象属性,实现其get和set方法。在get方法中,我们添加了一个依赖收集器Dep,它负责收集Watcher对象,而在set方法中,当其值被更改时,会触发notify方法,通知所有依赖(对应的Watcher对象)更新其视图。

  1. Watcher:

Watcher作为Observer和Vue之间的桥梁,负责监听数据的变化,并触发响应的更新。它需要接收一个update函数作为参数,在数据变化时调用。代码示例:

class Watcher {
  constructor(vm, expOrFn, cb) {
    this.vm = vm;
    this.getter = parsePath(expOrFn);
    this.cb = cb;
    this.value = this.get();
  }

  get() {
    window.target = this;
    const vm = this.vm;
    let value = this.getter.call(vm, vm);
    window.target = undefined;
    return value;
  }

  update() {
    const oldValue = this.value;
    this.value = this.get();
    this.cb.call(this.vm, this.value, oldValue);
  }
}

const bailRE = /[^\w.$]/;
function parsePath(path) {
  if(bailRE.test(path)) {
    return;
  }
  const segments = path.split('.');
  return function(obj) {
    for(let i = 0; i < segments.length; i++) {
      if(!obj) {
        return;
      }
      obj = obj[segments[i]];
    }
    return obj;
  }
}

在这段代码中,我们实现了一个Watcher类,它需要接收Vue实例、监听的表达式和回调函数。在get方法中,我们通过parsePath方法解析传入的表达式,获取相应数据,并将当前Watcher对象添加到收集器Dep中。在update方法中,我们触发回调函数,并传递新旧值作为参数。

至此,我们已经成功实现了Vue的Observer和Watcher。

下面是一个简单的示例,演示了如何使用Observer监听对象变化并触发响应的Watcher:

const obj = {a: 1, b: {c: 2}};
observe(obj);
new Watcher(obj, 'b.c', value => {
    console.log('b.c changed', value);
});
obj.b.c = 3; // 输出 "b.c changed 3"

再来一个示例,演示如何通过Watcher监听数组元素的变化:

const arr = [1, 2, 3];
observe(arr);
new Watcher(arr, 'length', value => {
    console.log('array length changed', value);
});
new Watcher(arr, '1', value => {
    console.log('array element changed', value);
});
arr.push(4); // 输出 "array length changed 4"
arr[1] = 5; // 输出 "array element changed 5"

在这个示例中,我们监听了数组的长度变化和第二个元素的变化,当数组长度或第二个元素发生变化时,Watcher对象会触发相应的回调函数。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:简单实现Vue的observer和watcher - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • Vue中的nextTick方法详解

    下面是Vue中的nextTick方法详解的完整攻略。 什么是nextTick方法 nextTick方法是Vue提供的一个异步操作工具,它可以让我们在DOM更新之后执行一些操作。它的作用是在下次DOM更新循环结束之后执行延迟回调,用于获得更新后的DOM。因此,使用nextTick方法可以让我们更加方便地操作更新后的DOM。 nextTick方法的基本应用 在V…

    Vue 2023年5月28日
    00
  • windows实现npm和cnpm安装步骤

    下面是详细讲解 “Windows 实现 npm 和 cnpm 安装步骤” 的完整攻略。 1. 下载并安装 Node.js 首先需要下载并安装 Node.js。进入 Node.js 官网,选择适合自己操作系统的版本,然后下载并安装。 2. 检查 Node.js 和 npm 是否安装成功 在命令行窗口中输入以下命令: node -v 如果输出 Node.js 的…

    Vue 2023年5月28日
    00
  • vue中的搜索关键字实例讲解

    下面给您讲解一下“vue中的搜索关键字实例讲解”的完整攻略。 标题 首先,我们需要明确本文的主题和目的。因为该文主要是讲解Vue中的搜索关键字实例讲解,所以我们可以将标题定为: # Vue中搜索关键字实例讲解 简介 在标题之后,我们需要对该文的主要内容进行简要介绍,让读者明确本文所要讲解的内容和解决的问题有哪些。比如: 本文将会详细讲解Vue中如何使用搜索关…

    Vue 2023年5月27日
    00
  • Ant Design Vue日期组件的时间限制方式

    Ant Design Vue 是 Ant Design 在 Vue 中的实现,是一套基于 Vue 实现的高质量 UI 组件库,拥有丰富的组件和良好的设计风格,深受前端工程师的喜爱。 Ant Design Vue 提供了日期组件,我们可以通过设置时间限制方式来限定用户选择日期的范围,例如限制用户只能选择今天及今天之后的日期,或者只能选择本月份的日期等等。 下面…

    Vue 2023年5月29日
    00
  • idea如何自动生成serialVersionUID

    首先需要明确的是,SerialVersionUID是Java序列化机制中一个非常重要的概念,它是用于识别不同版本类别的唯一识别码,常用于在网络传输和持久化对象时确定对象版本以便于正确地进行反序列化。 在IDEA中自动生成SerialVersionUID的方法如下: 进入IDEA设置界面:File -> Settings -> Editor -&g…

    Vue 2023年5月28日
    00
  • vue的事件绑定与方法详解

    下面是关于“vue的事件绑定与方法详解”的完整攻略。 什么是Vue事件绑定? 在Vue应用程序中,事件绑定用于监听DOM元素上的事件,以响应用户的交互操作。当用户对指定的DOM元素进行操作时,Vue会自动检测DOM事件,并触发指定的Vue方法。 事件绑定语法: <button v-on:click="doSomething">…

    Vue 2023年5月28日
    00
  • vue导出word纯前端的实现方式

    让我为您详细讲解一下“Vue导出Word纯前端的实现方式”的攻略。 1. 前置条件 在开始实现前,我们需要安装一些 npm 包和一些必备的工具,这些工具和包的详情如下: DocxTemplater:一个用于生成 docx 文档的工具 FileSaver.js:一个用于前端文件下载的 JS 库 Blob.js:一个 Blob 对象的 polyfill,用于处理…

    Vue 2023年5月27日
    00
  • 关于Vue v-on指令的使用

    关于Vue v-on指令的使用 在Vue中使用v-on指令可以实现事件监听和处理,常用于页面交互中。下面详细介绍v-on指令的使用方法。 语法 v-on指令是Vue提供的一种事件绑定方法,语法如下: v-on:事件名="事件处理函数" 其中,事件名指绑定的事件名称,事件处理函数是一个在Vue实例中定义的方法。 示例说明 示例1:点击事件 …

    Vue 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部