Vue3的响应式原理解析

Vue3的响应式原理解析

Vue2响应式原理回顾
// 1.对象响应化:遍历每个key,定义getter、setter
// 2.数组响应化:覆盖数组原型方法,额外增加通知逻辑
const originalProto = Array.prototype
const arrayProto = Object.create(originalProto);['push', 'pop', 'shift', 'unshift', 'splice', 'reverse', 'sort'].forEach(method => {arrayProto[method] = function () {originalProto[method].apply(this, arguments)notifyUpdate()}})
function observe (obj) {if (typeof obj !== 'object' || obj == null) {return}// 增加数组类型判断,若是数组则覆盖其原型if (Array.isArray(obj)) {Object.setPrototypeOf(obj, arrayProto)} else {const keys = Object.keys(obj)for (let i = 0; i < keys.length; i++) {const key = keys[i]defineReactive(obj, key, obj[key])}}
}
function defineReactive (obj, key, val) {observe(val) // 解决嵌套对象问题Object.defineProperty(obj, key, {get () {return val},set (newVal) {if (newVal !== val) {observe(newVal) // 新值是对象的情况val = newValnotifyUpdate()}}})
}
function notifyUpdate () {console.log('页面更新!')
}

vue2响应式弊端:
响应化过程需要递归遍历,消耗较大
新加或删除属性无法监听
数组响应化需要额外实现
Map、Set、Class等无法响应式
修改语法有限制

Vue3响应式原理剖析

vue3使用ES6的Proxy特性来解决这些问题。

function reactive (obj) {if (typeof obj !== 'object' && obj != null) {return obj}// Proxy相当于在对象外层加拦截// http://es6.ruanyifeng.com/#docs/proxyconst observed = new Proxy(obj, {get (target, key, receiver) {// Reflect用于执行对象默认操作,更规范、更友好// Proxy和Object的方法Reflect都有对应// http://es6.ruanyifeng.com/#docs/reflectconst res = Reflect.get(target, key, receiver)console.log(`获取${key}:${res}`)return res},set (target, key, value, receiver) {const res = Reflect.set(target, key, value, receiver)console.log(`设置${key}:${value}`)return res},deleteProperty (target, key) {const res = Reflect.deleteProperty(target, key)console.log(`删除${key}:${res}`)return res}})return observed
}
//代码测试
const state = reactive({foo: 'foo',bar: { a: 1 }
})
// 1.获取
state.foo // ok
// 2.设置已存在属性
state.foo = 'fooooooo' // ok
// 3.设置不存在属性
state.dong = 'dong' // ok
// 4.删除属性
delete state.dong // ok
嵌套对象响应式

测试:嵌套对象不能响应

// 设置嵌套对象属性
react.bar.a = 10 // no ok

添加对象类型递归

      // 提取帮助方法const isObject = val => val !== null && typeof val === 'object'function reactive (obj) {//判断是否对象if (!isObject(obj)) {return obj}const observed = new Proxy(obj, {get (target, key, receiver) {// ...// 如果是对象需要递归return isObject(res) ? reactive(res) : res},//...}
避免重复代理

重复代理,比如

reactive(data) // 已代理过的纯对象
reactive(react) // 代理对象

解决方式:将之前代理结果缓存,get时直接使用

const toProxy = new WeakMap() // 形如obj:observedconst toRaw = new WeakMap() // 形如observed:objfunction reactive (obj) {//...// 查找缓存,避免重复代理if (toProxy.has(obj)) {return toProxy.get(obj)}if (toRaw.has(obj)) {return obj}const observed = new Proxy(...)// 缓存代理结果toProxy.set(obj, observed)toRaw.set(observed, obj)return observed}// 测试效果console.log(reactive(data) === state)console.log(reactive(state) === state)

原创不易,还希望各位大佬支持一下\textcolor{blue}{原创不易,还希望各位大佬支持一下}

👍 点赞,你的认可是我创作的动力!\textcolor{green}{点赞,你的认可是我创作的动力!}

⭐️ 收藏,你的青睐是我努力的方向!\textcolor{green}{收藏,你的青睐是我努力的方向!}

✏️ 评论,你的意见是我进步的财富!\textcolor{green}{评论,你的意见是我进步的财富!}

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

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

相关文章

react Native 环境安装配置——图解版一目了然

✨原创不易&#xff0c;还希望各位大佬支持一下\textcolor{blue}{原创不易&#xff0c;还希望各位大佬支持一下}原创不易&#xff0c;还希望各位大佬支持一下 &#x1f525; Flutter和reactNative的区别\textcolor{green}{Flutter和react Native的区别}Flutter和reactNative的…

第七章 字典和集合[DDT书本学习 小甲鱼]【2】

7.1.2 字典的各种内置方法在序列里为不存在位置赋值&#xff0c;会出现错误&#xff1b;而在字典不存在得位置赋值&#xff0c;会创建。工厂函数&#xff08;类型&#xff09;以前学过 str(),int(),list(),tuple()....... 1.fromkeys() 用于创建和返回一个新的字典 不是修改 2…

Installing Node.js and Express on Ubuntu

Installing Node.js and Express on Ubuntu 1. 在nodejs官网上下载Linux Binaries(已经包含了npm):2. 安装Node.js下载后解压&#xff0c;并在解压的文件夹中启动Terminal后&#xff0c;输入命令&#xff1a; sudo cp * /usr/local/ -r再输入命令&#xff1a; node -v …

Chrome插件我只服你——10w人都在使用的浏览器插件

✨文章摘要导读\textcolor{blue}{文章摘要导读}文章摘要导读 &#x1f525; 为什么选择Chrome插件\textcolor{green}{为什么选择Chrome插件}为什么选择Chrome插件 &#x1f525; 插件具备的强大优势\textcolor{green}{插件具备的强大优势}插件具备的强大优势 &#x1f525; …

H3C通过端口ID决定端口角色

转载于:https://www.cnblogs.com/fanweisheng/p/11153312.html

特殊属性

转载于:https://www.cnblogs.com/mengbin0546/p/10338371.html

一款超强的手机屏幕投影工具

✨文章摘要导读\textcolor{blue}{文章摘要导读}文章摘要导读 &#x1f525; 前言\textcolor{green}{前言}前言 &#x1f525; 准备工作\textcolor{green}{准备工作}准备工作 &#x1f525; Scrcpy安装\textcolor{green}{Scrcpy安装}Scrcpy安装 &#x1f525; 工具调试\text…

长度不超过n的连续最大和___优先队列

题目链接: https://nanti.jisuanke.com/t/36116 题目: 在蒜厂年会上有一个抽奖&#xff0c;在一个环形的桌子上&#xff0c;有 nn 个纸团&#xff0c;每个纸团上写一个数字&#xff0c;表示你可以获得多少蒜币。但是这个游戏比较坑&#xff0c;里面竟然有负数&#xff0c;表示你…

JS一维数组转化为三维数组有这个方法就够了

今天在CSDN上问答区看到一个提问的小伙伴&#xff0c;是想要将一维数组转化为三位数组的需求&#xff0c;正好不是很忙&#xff0c;乐于助人的我立马给这位同学安排上 下面是后端同学返给我们的一维数组数据格式 [{品牌: xiaomi, 机型: 10, 配置: 512},{品牌: xiaomi, 机型: 10…

Hadoop集群安装

一、完全分布式模式的安装和配置的具体步骤&#xff1a; 1.配置jdk&#xff1b;2.配置hosts文件&#xff1b;3.建立hadoop运行账号&#xff1b;4.配置ssh免密码连入&#xff1b; 5.下载并解压hadoop安装包&#xff1b;6.配置namenode&#xff0c;修改site文件&#xff1b;7.配置…

11系列

梦想这东西和经典一样 永远不会随时间而褪色 反而更显珍贵转载于:https://www.cnblogs.com/tianjinquan/archive/2010/11/03/1867694.html

webpack相关配置

文章目录&#x1f4a6; webpack的概念&#x1f4a6; webpack的基本使用项目目录并初始化创建首页及js文件以jQuery为例安装jQuery导入jQuery安装webpack&#x1f4a6; webpack的相关设置设置webpack的打包入口/出口设置webpack的自动打包配置html-webpack-pluginwebpack中的加载…

Day 21 20190205 老男孩python学习第21天 内容整理

今天写作业&#xff0c;明天后天要在外旅游 写作业写了7个小时。 1 def read_file_as_dict(where):2 staff_dict {}3 f open(%s % where, mode"r", encodingutf-8)4 data f.read()5 f.close()6 row data.strip().split(\n)7 for staff i…

SCOM 简单界面操作指南 [SCOM中文系列之三]

今天大概介绍下SCOM的管理界面&#xff0c;大概分三个重要的功能版块 Monitoring 监控版面 Authoring &#xff08;中文版不知道翻译成什么&#xff0c;主要编辑MP&#xff09; Administration 管理操作 首先说一下管理操作区&#xff0c;开始装好的SCOM都需要来这里配置一下的…

趁着对象泡脚的功夫,我把vueX吃透了

文章目录vueX&#x1f31f;Vuex的概述什么是vuexVuex管理数据的优点&#x1f31f;Vuex的基本使用步骤1.安装 npm i vuex --save2.在src文件目录下新建store>index.js文件3.口文件里面引入store&#xff0c;然后再全局注入4.使用&#x1f31f;Vuex中的核心特性State在组件中访…

【题解】FBI序列

题目描述 两伙外星人策划在未来的XXXX年侵略地球&#xff0c;侵略前自然要交换信息咯&#xff0c;现在&#xff0c;作为全球保卫队队长&#xff0c;你截获了外星人用来交换信息的一段仅由“F”&#xff0c;“B”&#xff0c;“I”&#xff0c;“O”组成的序列。为了保卫地球和平…

vue基础(上篇)

✨有粉丝在私信中联系博主&#xff0c;希望博主能够系统的出一篇关于vue的基础篇\textcolor{blue}{ 有粉丝在私信中联系博主&#xff0c;希望博主能够系统的出一篇关于 vue的基础篇}有粉丝在私信中联系博主&#xff0c;希望博主能够系统的出一篇关于vue的基础篇 ✨ 今天他来了…

depends用于测试程序运行所缺少的文件,可以帮我们很快找到问题

DEPENDS工具和DUMPBIN工具使用阅读目录(Content) 1.Depends2.DUMPBIN2.1 开启CMD2.2 移动目录到C:\Program Files (x86)\Microsoft Visual Studio\VC98\Bin2.3 运行命令:VCVARS32.BAT2.4 下面就可以调用dumpbin.exe命令了在系统部署运行时我们经常发现某个程序在开发机器中可以…

友联

欢迎来到小站友链区&#xff0c;欢迎━(&#xff40;∀)ノ亻!。 ljc20020730学长巨佬_WA自动机珂朵莉最可爱了BLUESKY007雷姆最可爱啦扬子曰他的代码是神奇的lukelin机房最强如果你想要成为chhokmah小站的朋友的话&#xff0c;请你先把小站加入为友链站哟(&#xff3e;&#xf…

vue基础(中篇)

✨有粉丝在私信中联系博主&#xff0c;希望博主能够系统的出一篇关于vue的基础篇\textcolor{blue}{ 有粉丝在私信中联系博主&#xff0c;希望博主能够系统的出一篇关于 vue的基础篇}有粉丝在私信中联系博主&#xff0c;希望博主能够系统的出一篇关于vue的基础篇 ✨ 今天他来了…