Vue3 中的数据侦测的实现

Vue3 中的数据侦测是通过 Proxy 实现的。当我们创建一个响应式对象时,Vue3 内部会使用 Proxy 将其转化成一个响应式对象。当我们访问对象中的属性时,Vue3 会自动追踪这个属性,并将这个属性添加到依赖列表中。当响应式对象中的属性发生改变时,Vue3 就会更新视图。

下面我们来看具体的实现步骤:

使用 createReactiveObject 创建响应式对象

Vue3 使用 createReactiveObject 来创建响应式对象。createReactiveObject 函数接受 3 个参数:target、proxy、baseHandlers。其中,target 是我们要转化为响应式的对象,proxy 是一个 Proxy 实例,baseHandlers 是一个包含 get 和 set 函数的对象。

const target = {};
const proxy = new Proxy(target, baseHandlers);
const baseHandlers = {
  get: function(target, prop) {
    // get方法实现省略...
  },
  set: function(target, prop, value) {
    // set方法实现省略...
  }
};
const reactiveObj = createReactiveObject(target, proxy, baseHandlers);

实现 get 和 set 方法

我们需要在 baseHandlers 中实现 get 和 set 方法来拦截对象的读取和设置操作。

针对访问操作,get 方法应该执行以下操作:

  • 获取属性值并返回。
  • 如果当前属性只能读取而无法修改,则不将其添加到依赖列表中。
const baseHandlers = {
  get: function(target, prop, receiver) {
    let value = Reflect.get(target, prop, receiver);
    // 将当前属性添加到依赖列表中
    track(target, 'get', prop);
    return value;
  },
  set: function(target, prop, value, receiver) {
    let oldValue = Reflect.get(target, prop, receiver);
    let res = Reflect.set(target, prop, value, receiver);
    // 将当前属性对应的依赖列表中的所有 effect 都执行一遍
    trigger(target, prop, value, oldValue);
    return res;
  }
};

针对修改操作,set 方法应该执行以下操作:

  • 设置属性值。
  • 将当前属性对应的依赖列表中的所有 effect 都执行一遍。

追踪依赖项

我们需要在 track 函数中实现依赖追踪功能。track 函数接受 3 个参数:target、type、key。其中,target 是我们要追踪的对象,type 是追踪类型(取值可以为 'get' 和 'set'),key 是我们追踪的属性名称。

let activeEffect = null;
const targetMap = new WeakMap();

function track(target, type, key) {
  // 如果不存在活跃的 effect,则直接返回
  if (!activeEffect) {
    return;
  }
  let depsMap = targetMap.get(target);
  // 如果当前对象还没有依赖列表,则创建一个新的依赖列表
  if (!depsMap) {
    depsMap = new Map();
    targetMap.set(target, depsMap);
  }
  let dep = depsMap.get(key);
  // 如果当前属性还没有依赖列表,则创建一个新的依赖列表
  if (!dep) {
    dep = new Set();
    depsMap.set(key, dep);
  }
  // 把当前活跃的 effect 添加到依赖列表中
  dep.add(activeEffect);
}

触发更新

我们需要在 trigger 函数中实现更新操作。trigger 函数接收 4 个参数:target、key、newValue、oldValue。其中,target 是我们要更新的对象,key 是我们要更新的属性名称,newValue 是更新后的新值,oldValue 是更新前的旧值。

function trigger(target, key, newValue, oldValue) {
  let depsMap = targetMap.get(target);
  if (!depsMap) {
    // 当前对象没有依赖列表,说明没有 effect 依赖当前对象,则直接返回
    return;
  }
  let dep = depsMap.get(key);
  if (dep) {
    // 如果当前属性对应的依赖列表中存在 effect,则执行这些 effect
    dep.forEach(effect => {
      effect(target, key, newValue, oldValue);
    });
  }
}

以上是 Vue3 中数据侦测的实现过程,下面给出具体的示例代码。

示例一

在这个示例中,我们创建一个响应式的对象 obj,当我们读取 obj 的属性时,它会自动添加到依赖列表中。

let target = { a: 1 };
let reactiveObj = reactive(target);

effect(() => {
  console.log(reactiveObj.a);
});

// 控制台输出:1

示例二

在这个示例中,我们创建一个响应式的对象 obj,然后我们通过改变 obj 中的值,触发依赖列表中的函数执行。

let target = { a: 1 };
let reactiveObj = reactive(target);

effect(() => {
  console.log(reactiveObj.a);
});

reactiveObj.a = 2; // 控制台输出:2

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue3 中的数据侦测的实现 - Python技术站

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

相关文章

  • vue数字类型过滤器的示例代码

    下面是关于Vue数字类型过滤器的示例代码攻略。 什么是Vue数字类型过滤器? Vue数字类型过滤器是一种可以用来格式化数字的针对Vue的特殊标签。它可以使数字看起来更清晰易读,便于用户查看。 示例一:货币符号格式化 当我们需要将一个数字格式化成货币的形式时,可以通过使用Vue数字类型过滤器来实现这一目的。下面是一个带有货币符号的数字类型过滤器的示例代码: &…

    Vue 2023年5月29日
    00
  • vue + elementUI实现省市县三级联动的方法示例

    下面我将为您详细讲解“vue + elementUI实现省市县三级联动的方法示例”的完整攻略。 1. 确定数据来源 实现省市县三级联动功能,首先需要确定数据来源,可以在后端中获取,也可以使用前端数据。本文以前端数据为例,数据格式如下: const regionData = [ { value: ‘110000’, label: ‘北京市’, children…

    Vue 2023年5月28日
    00
  • 详解Vue之事件处理

    详解Vue之事件处理 Vue.js 是一款流行的前端框架,它的事件处理能力非常强大。本文将详细讲解 Vue.js 中的事件处理,包括如何使用 v-on 指令绑定事件、如何传递参数和修饰符、以及如何使用自定义事件等。 绑定事件 在 Vue.js 中,我们可以使用 v-on 指令来绑定事件。省略了 v-on 直接写 @ 符号,作用相同,下面的几个示例中直接使用 …

    Vue 2023年5月27日
    00
  • vue2.0 自定义日期时间过滤器

    下面是“vue2.0自定义日期时间过滤器”的完整攻略: 1. 什么是过滤器? 过滤器是Vue.js中一种很常见的处理数据的方式,本质上它就是一种特殊的函数,可以用在一些绑定表达式中(从模型到视图和从视图到模型)。 2. 自定义日期时间过滤器的步骤 下面通过一步一步的操作来完成自定义日期时间过滤器的任务: 2.1 安装moment.js moment.js是一…

    Vue 2023年5月28日
    00
  • vue实现电子时钟效果

    Vue实现电子时钟效果 我们可以使用Vue框架实现一个电子时钟效果,以下是完整步骤: 步骤1:创建Vue实例 首先在HTML页面中引入Vue.js文件,然后创建一个Vue实例,代码如下: <div id="clock"> {{ currentTime }} </div> <script src="h…

    Vue 2023年5月28日
    00
  • 详解vue-cli3开发Chrome插件实践

    详解vue-cli3开发Chrome插件实践 前言 Vue-CLI 3是Vue.js发布的脚手架构建工具。它易于使用,且支持自定义配置,本文就是基于Vue-CLI 3来开发Chrome插件的。 环境 在开始之前,确保本地已经安装了Node.js和Vue-CLI 3,安装方法如下: 1.下载 Node.js:https://nodejs.org/en/down…

    Vue 2023年5月27日
    00
  • 15分钟学会vue项目改造成SSR(小白教程)

    下面是关于“15分钟学会vue项目改造成SSR(小白教程)”的完整攻略。 什么是SSR? SSR(Server Side Rendering)即服务端渲染,根据服务端返回的数据,在服务端生成HTML字符串,然后将其发送给客户端进行展示。与传统的SPA(Single Page Application)相比,SSR能够优化页面的SEO和首屏加载速度。 如何将Vu…

    Vue 2023年5月27日
    00
  • vue3的动态组件是如何工作的

    Vue3 的动态组件相比于 Vue2 有了较大的改变,本文将详细讲解 Vue3 的动态组件是如何工作的,包括其实现原理和示例说明。 什么是动态组件 Vue 中的组件是指可复用并具有独立功能的代码块,根据其作用域及其之间的交互可以实现复杂的组件化应用。而动态组件,顾名思义指在运行时可以动态地切换所渲染的组件。 Vue3 中动态组件的实现原理 在 Vue2 中,…

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