Vue2和Vue3的双向数据绑定原理

news2024/12/29 12:48:57

目录

  • 前言:
  • vue2.x 是如何实现响应式系统的:
  • defineProperty 的痛点:
  • Object.defineProperty 代码的使用
  • Proxy 方法的理解
  • Proxy 代码的使用:
  • 总结:

前言:

今天小编给大家讲解一下,Vue2和Vue3的双向数据绑定原理。

我正在参加 2022年「博客之星」年度总评选,请大家帮我支持一下,给我一个五星。
|
点击前往我的评选页面:
|
在这里插入图片描述
大家只要按图给我五星即可,谢谢大家的帮助。

vue2.x 是如何实现响应式系统的:

当你把一个普通的 js 对象传入 vue 实例作为 data 选项,vue 将遍历此对象的所有prototype(属性),并使用 object.defineProperty(),将这些 prototype(属性),全部转换为 getter / setter,在 getter 中收集数据依赖,在 setter 中监听数据变化,一旦数据发生改变,在通知订阅者。

每个组件实例,都对应一个 watcher 实例,它会在组件渲染的过程把 “接触” 过的数据 prototype(属性)记录为依赖,之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染;


defineProperty 的痛点:

  1. 它无法发现对象新增和被删除的属性,当你给一个对象添加一个新的属性,这个新增的属性没有添加到 vue 的数据更新侦查机制里;

Vue.set() 可以让 vue 知道你新增了一个属性,其实 Vue.set 可以让 Vue 知道新增了一个属性。其实 set() 内部也是通过调用 defineProperty() 来实现;

  1. 当你利用索引直接设置一个数组(new Array(4))或者修改数组的长度时,Vue 不能检测到数组的变动;
  2. 当对象嵌套的层数特别深(多层嵌套)的时候,递归遍历带来的性能开销就会比较大;

Object.defineProperty 代码的使用

mounted() {
    // 先定义好一套规则
    class Observer {
      constructor(data) {
        for (let key of Object.keys(data)) {
          if (typeof data[key] === "object") {
            data[key] = new Observer(data[key]);
          }
          Object.defineProperty(this, key, {
            enumerable: true,
            configurable: true,
            get() {
              console.log("You visited" + key);
              return data[key];
            },
            set(NewValue) {
              console.log("You set" + key);
              console.log("New Value" + NewValue);
              if (NewValue === data[key]) {
                return;
              }
              data[key] = NewValue;
            },
          });
        }
      }
    }
    let obj = {
      name: "app",
      age: 18,
      a: {
        b: 1,
        c: {
          d: 1,
        },
      },
    };
    let app = new Observer(obj);
    console.log(app);
    app.age = 20;
    app.newProperty = "new attrs";
    console.log(app);
  },

结果:
在这里插入图片描述


Proxy 方法的理解

Proxy 在 vue3.0 中上位

可以解决 defineProperty 的痛点,因为本质的原因在于 Proxy 是内置了拦截器对象。所有的外部访问都得先经过这一层拦截,不管是先前定义好的,还是新增的属性,又或者是深层的嵌套属性,访问时都会被拦截;

Reflect.set()方法用于设置对象属性的值,1:目标对象:2:改变参数的名称:3:改变参数的值:4:值是this如果遇到设置器,将提供给目标调用。
此方法返回一个布尔值,该值指示该属性是否已成功设置。


Proxy 代码的使用:

mounted() {
    const obj = {
      name: "app",
      age: 19,
      a: {
        b: 1,
        c: 2,
      },
    };
    const p = new Proxy(obj, {
      get(target, propKey, receiver) {
        console.log("Your visited:" + propKey);
        // Reflect.set()方法用于设置对象属性的值:1:目标对象:2:改变参数的名称:3:改变参数的值
        // 此方法返回一个布尔值,该值指示该属性是否已成功设置。
        return Reflect.set(target, propKey, receiver);
      },
      set(target, propKey, value, receiver) {
        console.log("You set:" + propKey);
        console.log("New value:" + value);
        // Reflect.set()方法用于设置对象属性的值,1:目标对象:2:改变参数的名称:3:改变参数的值:4:值是this如果遇到设置器,将提供给目标调用。
        // 此方法返回一个布尔值,该值指示该属性是否已成功设置。
        return Reflect.set(target, propKey, value, receiver);
      },
    });
    p.age = "20";
    console.log(p);
    p.newProperty = "New attribute";
    console.log(p);
  },

结果:
在这里插入图片描述


总结:

  1. proxy 是用来操作对象并且扩展对象能到,而 Object.defineProperty() 只是单纯的操作对象的属性;
  2. Vue2.X 是用 Object.defineProperty() 实现数据响应的,但是受限于 defineProperty() 的实现,必须递归遍历至对象的最底层;
  3. vue3.0 用 Proxy 来拦截对象,不管对目标执行任何操作,都会先通过 Proxy 的处理逻辑;
  4. 除了 Vue3.0,还有其他的库也在使用 Proxy。

最后还请大家帮我点击一下,谢谢大家的帮助

我正在参加 2022年「博客之星」年度总评选,请大家帮我支持一下,给我一个五星。
|
点击前往我的评选页面:
|
在这里插入图片描述
大家只要按图给我五星即可,谢谢大家的帮助。


以上就是 Vue2和Vue3的双向数据绑定原理,不懂得也可以在评论区里问我或私聊我询问,以后会持续发布一些新的功能,敬请关注。
我的其他文章:https://blog.csdn.net/weixin_62897746?type=blog

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/126511.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CAPL学习之路-测试功能集函数(诊断测试)

TestCollectDiagEcuInformation 向诊断目标的诊断类下的所有诊断服务发送诊断请求,并将诊断响应写入测试报告中 testcase TCExample() {int status;status = TestCollectDiagEcuInformation( "Door", "Sessions");if( status == 0)TestStepPass( "EC…

javaweb项目接入CAS单点认证(含自身系统的三员过滤)

一、搭建cas server 1.下载war包 2.打开cmd窗口执行以下命令,命令如下(指定ip): keytool -genkey -v -alias casbm -keyalg RSA -keystore D:\cas\keystore\casbm.keystore -ext SANIP:192.168.2.166 3.我们生成秘钥库后需要从秘钥库中导出证书&#x…

D. Distinct Characters Queries(set维护)

Problem - 1234D - Codeforces 给你一个由小写拉丁字母组成的字符串s和对这个字符串的q个查询。 回顾一下,字符串s的子串s[l;r]就是字符串slsl1...sr。例如,"codeforces "的子串是 "code"、"force"、"f"、&quo…

spring6(概念;ioc详解,各种数据的注入方式)

第一章 启示录 一个普通的三层架构,不借助spring的情况下。需要程序员自己去new对象。 如果使用这种方式,那么代码上就把功能写死了,这时候需要更改一个数据库连接。这是时候数据交互层的代码就需要修改。这违背了OCP开闭原则。 1.1 OCP开闭…

Bert 得到中文词向量

通过bert中文预训练模型得到中文词向量和句向量,步骤如下: 下载 bert-base-chiese模型 只需下载以下三个文件,然后放到bert-base-chinese命名的文件夹中 得到中文词向量的代码如下 import torch from transformers import BertTokenizer,…

can8.0-基础知识

1、canopen协议概述 1.1对象字典 CANopen 协议采用了带有 16 位索引和 8 位子索引的对象字典,对象字典的结构如表 1.2 常用的通信对象 1) 网络管理对象 (NMT) 2) 服务数据对象 (SDO) 3) 过程数据对象 (PDO) 4) 同步对象 (SYNC) 5) 紧急报文 (EMCY) 1.3 通信对象…

PISR 数据库,区块链和大数据的下一个最佳结合

据集合。如今,在大数据时代,数据管理越来越受到重视,已经成为一项非常重要的资产。因此,数据安全也变得越来越重要,应该引起重视。尽管现有数据库可以满足单个公司的存储依赖性,但它们很难确保公司之间协作…

React学习03-基于脚手架的React应用

初始化脚手架 使用 npx 创建 npx create-react-app 项目名使用 npm install 创建 全局安装create-react-app包: npm install -g create-react-app创建脚手架: create-react-app 项目名npm 镜像 执行 create-react-app时,还会自动安装一…

C++程序员学习资料汇总

小白入门 计算机网络微课堂(有字幕无背景音乐版) 非常适合小白学习,没有废话,非常生动 《计算机是怎样跑起来的》 《程序是怎样跑起来的》 《网络是怎样连接的》 基础 资料名备注状态阅读时间《深入理解计算机系统》很多大厂面…

实验室预约系统|基于Springboot+Vue实现学校实验室预约管理系统

作者主页:编程指南针 作者简介:Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容:Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

JAVA中那些令人眼花缭乱的锁

一、开局一张图带你了解java相关的锁 二、乐观锁和悲观锁 1、悲观锁 悲观锁对应于生活中悲观的人,悲观的人总是想着事情往坏的方向发展。 举个生活中的例子,假设厕所只有一个坑位了,悲观锁上厕所会第一时间把门反锁上,这样其他…

python pyqtgraph绘图库

pyqtgraph官网 PyQtGraph被大量应用于Qt GUI平台(通过PyQt或PySide),因为它的高性能图形和numpy可用于大量数据处理。 特别注意的是,pyqtgraph使用了Qt的GraphicsView框架,它本身是一个功能强大的图形系统; 我们将最优…

知识付费海哥:这样做课,不赚钱都难

现在不少人开始了开发网课,卖网课赚钱, 但是在网课开发时,很多人开始的时候,关注的点就错了! 自己喜欢钓鱼,就开发钓鱼的课, 自己喜欢演讲,就开发演讲的课, 自己喜欢…

Dubbo入门(二)——IDEA下Dubbo+Zookeeper搭建

目录一、Zookeeper1.1 下载1.2 安装1.3 修改配置文件1.4 启动二、Dubbo插件搭建三、手动创建3.1 创建项目3.1.1 pom依赖3.2 api模块3.2.1 pom依赖3.2.2 实体类3.2.3 service接口3.3 provider3.3.1 pom依赖3.3.2 配置文件3.3.3 mapper3.3.4 service实现类3.3.5 启动类3.4 consum…

冶金工艺流程(钢铁全流程)

工艺图 工艺讲解 生产流程从矿石原料采集开始,对于低品位的矿石,必须在冶炼前经选矿工序先选出铁精矿,然后进一步制成烧结矿或球团矿。 ————————————————————————————— 高炉冶炼是一个连续的、大规模的高温生产过程。铁矿石…

为什么Aruba始终走在网络世界的前列?

编辑 | 阿冒 设计 | 沐由关于网络的价值,梅特卡夫定律(Metcalfes law)曾经在多年前就明白无误地告诉我们:VKN。其中,V代表一个网络的价值,N代表这个网络的节点数,K代表价值系数。如果梅特卡夫…

47. 批量规范化 代码从零开始实现 + 简洁实现

1. 从零实现 下面,我们从头开始实现一个具有张量的批量规范化层。 import torch from torch import nn from d2l import torch as d2l# X是输入,gamma, beta是两个可以学习的参数,moving_mean, moving_var是整个数据集的均值和方差&#xf…

ssh登录——scp传文件

一、ssh登录 1.基本用法 远程登录服务器: ssh userhostname# user: 用户名 # hostname: IP地址或域名 第一次登录时会提示: The authenticity of host 123.57.47.211 (123.57.47.211) cant be established. ECDSA key fingerprint is SHA256:iy237y…

十分钟掌握 “UML ” 的基本使用

十分钟掌握 “UML ” 的基本使用 每博一文案 很喜欢这样一段话:内可以不跟别人计较,但一定要学会维护自己,你可以不跟别人争抢,但应该懂得远离小人。 人生在世,我们会遇到形形色色的人,人心隔肚皮&#xf…

Pytorch深度学习实战——第3章课后习题

1.从list(range(9))list(range(9))list(range(9))中创建一个张量aaa并预测检查其大小、偏移量、步长。 import torch atorch.tensor(list(range(9))) print(a.storage_offset())#偏移量 print(a.stride())#步长 print(a.size())#大小a)使用ba.view(3,3)ba.view(3,3)ba.view(3,…