vue2和vue3的响应式原理

2023-10-27

vue2和vue3的响应式原理

vue2 的响应式

使用 Object 构造函数上 defineProperty() 实现

存在的问题 :

  • 对象 新增的属性没有响应式
  • 数组 部分操作没有响应式

解决办法

1、 用 Vue.set 进行添加或修改,Vue.delete进行删除。
2、使用数组的一些方法对数组操作 (如 push()splice()pop()shift()unshift()sort()reverse()
3、使用 vue 实例对象上的 $set进行添加或修改, $delete 进行删除。
4、使用 vue实例对象上的 $nextTick 进行页面更新

实现响应式的原理

  • 对象类型: 通过 Object.defineProperty() 对属性的读取,修改进行拦截(数据劫持)
  • 数组类型: 通过重写更新数组的方法来实现拦截(对数组的变更方法进行包裹)

Object.defineProperty参数说明

Object.defineProperty("对象", "属性", {
	value: 0, // 属性值
	enumerable: true, // 属性是否可被枚举,默认 false
	writable: true, // 属性是否可被修改,默认 false
	configurable: true, // 属性是否可被删除,默认 false
	get() {}, // 获取属性值时调用,此函数需返回属性的属性值
	set(value) {}, // 修改属性值时调用,value为修改后的值
})

vue2 实现响应式

// 定义源对象
let person = {
	name:"张三",
	age:18
}

// 定义代理对象
let obj = {}
Object.defineProperty(obj ,"name",{
       get(){
           return person.name
       },
       set(val){
           console.log(val)
           person.name = val +"aaa"
       }
    })
console.log(obj .name);
obj.name = "李四"
// 更改obj.name的值,会触发set方法
console.log(person) // name = "李四aaa" 因为set方法return时是val+"aaa"

vue3 的响应式

使用 window 上的内置构造函数 Proxy 实现。

实现原理

  • Proxy(代理): 拦截对象中任意属性的变化,包括属性值的读取、修改,以及属性的添加和删除
  • Reflect(反射): 对源对象的数学进行操作。
// 定义源对象
let person = {
    name:"zhangsan",
    age:18
}
// 定义代理对象
  let p = new Proxy(person,{
       // target:源对象,key:源对象的属性名,val:源对象的属性值,receiver:代理对象,一般不用,可以不写,默认是代理对象,也就是p,如果写了,就是写的值,比如写了p1,那么就是p1,如果不写,就是p
       get(target,key){
           return target[key]
       },
       // val:更改后的值,也就是p.name = "lisi"中的lisi,也就是set方法中的val,也就是p.name = val中的val
       set(target,key,val){
           console.log(val)
           target[key] = val +"aaa"        
       },
       deleteProperty(target,key){
           console.log(target,key)
           return delete target[key]     
       }
   })
  console.log(p);

但是上述代码依然存在问题。例如:

const p1 = Object.defineProperty(person,"name",{
	get(){
		return "李四"
	}
})

// 在这里会出现异常
const p2 = Object.defineProperty(person,"name",{
	get(){
		return "王五"
	}
})
console.log(person)

在上述代码中,因为我们重复的对 personname属性进行了操作,就会出现异常,导致单线程挂掉,如果需要解决出现的问题,需要用try...catch 对异常进行捕获

同时,我们也可以用 Reflect 处理这种问题

Relectwindow 上的内置构造函数,与 Object 不同的是,Reflect 会返回一个布尔值,可以更灵活地捕捉到异常,判断操作是否成功,从而进一步对错误进行抛出

实现响应式可以优化为:

  let p = new Proxy(person,{
       get(target,key){
           return Reflect.get(target,key)
       },
       set(target,key,val){
           return Reflect.set(target,key,val)        
       },
       deleteProperty(target,key){
           return Reflect.deleteProperty(target,key)     
       }
   })
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue2和vue3的响应式原理 的相关文章

随机推荐

  • 深入理解Java虚拟机jvm-栈溢出-对象引用过多java.lang.StackOverflowError

    对象引用过多 示例 结果 原因分析 示例 栈溢出 栈内存过小 对象引用过多 java lang StackOverflowError 输出 stack length 344 public class Demo3 private static
  • CTFshow sql注入 上篇(web171-220)

    目录 前言 题目 web 171 万能密码 web 172 回显内容过滤 base64或者hex编码绕过 web 173 回显内容过滤 base64或者hex编码绕过 web 174 布尔盲注丶trim盲注丶replace替换字符 web
  • Cmake 中 file、message和add_executable解析

    file 为cmake中文件操作时用的语句 比如文件的创建 读写 等操作都是通过file来操作的 GLOB file GLOB variable RELATIVE path FOLLOW SYMLINKS globbing expressi
  • DVWA靶场下的sql注入之文件读写

    DVWA的安装配置在我上一篇文章上写过了 不知道的可以去看看 这里直接讲sql注入如何获得文件读写权限 sql注入读写的根本条件 1 数据库用户得是高权限用户 root 2 数据库下的secure file priv不是null 如果是也可
  • 文档在线预览(三)使用js前端实现word、excel、pdf、ppt 在线预览

    关于实现文档在线预览的做法 之前文章提到了的两种实现方式 1 通过将文档转成图片 详见 文档在线预览 一 通过将txt word pdf转成图片实现在线预览功能 2 将文档转成html 详见 文档在线预览 二 word pdf文件转html
  • 运放自激振荡的补偿

    运放的相位补偿 为了让运放能够正常工作 电路中常在输入与输出之间加一相位补偿电容 1 关于补偿电容 理论计算有是有的 但是到了设计成熟阶段好象大部分人都是凭借以前的调试经验了 一般对于电容大小的取值要考虑到系统的频响 简单点说加的电容越大
  • 职场工作与生活

    序言 和很多在CSDN的博主一样 大家在工作之后就很少或者是不再回到CSDN 确实自己也一年多没上了 因为可能当初大家在这就是为了记录和分享当初自己学习技术的东西 而大家走出象牙塔开始工作后 发生了很大的转变 在国内大多数搞技术的工作要求保
  • Beam数据流水线——Pipeline

    目录 Beam简介 基本概念 数据流水线 Beam数据流水线的应用 Beam数据流水线的处理模型 Beam数据流水线的错误处理 单Transform错误处理 多步骤Transform错误处理 Beam简介 Apache Beam 是Goog
  • 工厂的进化

    本文从一个简单示例的需求不断衍化过程 来分析理解简单工厂 工厂方法 抽象工厂模式 首先看一下初始示例 public interface Car public void drive public class BenzCar implement
  • js 实现刷新页面 保留当前tab切换状态

    div class mes tab div class tab tit flexbetween span 报考指南 span span 考研院校 span span 考研专业 span span 备考资料 span span 复试调剂 sp
  • ImportError: No module named typing

    python版本 2 7 错误 使用pip时出现该错误 Traceback most recent call last File C Python27 Scripts pip script py line 9 in load entry p
  • iframe如何发送请求_Vue 中使用 Iframe 踩坑记

    背景 创业项目使用的 Vue 开发前端 最近在开发的一个需求涉及到了 Iframe 的使用 为了让父子页面能够正常通信 头都搞大了 不过最终是解决了问题 写篇文章记录下 利人利己 难点 之前没有在 Vue 中使用过 Iframe 网上的相关
  • 【环境搭建】Docker上搭建sqli-labs漏洞环境

    目录 1 sqli labs简介 2 Docker搭建sqli labs 3 总结 参考文献 1 sqli labs简介 sq Ii labs是一款学习SQL注入的开源平台 共有75种不同类型的注入 官方介绍如下 SQLI LABS is
  • 基于VMD-SSA-LSTM的多维时序光伏功率预测

    目录 1 主要内容 变分模态分解 VMD 麻雀搜索算法SSA 长短期记忆网络LSTM 2 部分代码 3 程序结果 4 下载链接 1 主要内容 之前分享了预测的程序基于LSTM的负荷和可再生能源出力预测 核心部分复现 该程序预测效果比较好 并
  • RT-Thread uart2串口dma idle接收不断帧

    硬件STM32F407 IDE使用RT Thread Studio uart2串口使用这两个引脚 功能 IO端口 UART2 TX PA2 UART2 RX PA3 UART2 DMA接收配置 先使能DMA接收 RX缓冲区可以稍微调大些 b
  • Vuetify笔记(5):data-tables组件

    v data table 用于显示表格数据 功能包括排序 搜索 分页 行内编辑 头部提示以及行选择 而我们在实际应用中使用最多的就是服务端分页和排序 如果你从后台加载数据 并希望显示结果之前进行分页和排序 你可以使用 total items
  • 对象的构造和析构

    对象的构造和析构 1 对象的初始化和清理 构造函数 和 析构函数 被编译器自动调用完成对象初始化和对象清理工作 2 构造函数 和 析构函数 构造函数写法 与类名相同 没有返回值 不写void 可以有参数 可以发生重载 构造函数由编译器自动调
  • 神经网络学习——图像篡改

    记录 这是课堂上做的一个关于图像篡改识别的题目 因为前后花的时间比较多 虽然最后实现的效果也不怎么行 但是这个过程踩了很多坑 这里记录一下 文章目录 记录 前提 题目分析 网络搭建 依赖包 数据读取处理 网络搭建 训练参数 预测函数 模型保
  • linux——read和write函数实现cp、用户级缓冲预读入缓冲的简单认识

    用read和write实现cp 1 注意头文件 2 fd1是源文件 传入参数中的第一个 fd2是目标文件 传入参数中的第二个 要写入的文件至少可写 如果没有当前文件就创建文件并设置权限 如果已经有文件就截断为0再重新写 3 定义一个缓冲区
  • vue2和vue3的响应式原理

    vue2和vue3的响应式原理 vue2 的响应式 vue3 的响应式 vue2 的响应式 使用 Object 构造函数上 defineProperty 实现 存在的问题 对象 新增的属性没有响应式 数组 部分操作没有响应式 解决办法 1