Vue 3 深入响应性原理

Easter79
• 阅读 619

深入响应性原理

终于到了讲解我们 Vue 的响应式原理,前面我们已经讲解了 MapWeakMapSetWeakSetProxyReflect 这几个知识点。那么接下来思考下到底什么是响应式,就比如我们做一个公司的官网,然后要求必须兼容手机端,ipad 端,电脑端,内容屏幕大小变化而变化,这些就需要依赖 JavaScript,CSS, HTML 去处理了。

那么假如我们像在 Excel 表格中,两个数字相加,如果一个数字变化了,两个数字的和肯定得变化吧,Excel 表格做到了,可定里面是做了很大的处理了,那如果使用 JavaScript 来做,我们该如何做呢?

`let var1 = 2
let var2 = 3

let sum = var1 + var2

// 当 var1 变化时,

// 该如何通知 sum
`

如果我们更新第一个值,sum 不会被修改。

那么我们如何用 JavaScript 实现这一点呢?

  • 检测其中某一个值是否发生变化

  • 用跟踪 (track) 函数修改值

  • 用触发 (trigger) 函数更新为最新的值

Vue 如何追踪变化?

在 Vue 中,在将一个对象数据传递给一个组件的时候,Vue 已经给我这些数据设置了 settergetter 属性,一旦数据发生变化,就会得到响应,这其中就是 ProxyReflect 的很大的功劳。

通过前面的知识,我们知道 Proxy 是一个包含另一个对象或函数并允许你对其进行拦截的对象。

let obj = {     var1: 2,     var2: 3,     sum: 0, } let handlerObj = {     get(target, prop) {         if(prop == 'sum') {             target['sum'] = target['var1'] + target['var2']             return target['sum']         }         return target[prop]     },     set(target, prop, newVal) {         target[prop] = newVal     } } let p = new Proxy(obj, handlerObj) console.log(p.sum)

Vue 3 深入响应性原理

此外,Proxy 还提供了另一个特性。我们不必像这样返回值:target[prop],而是可以进一步使用一个名为 Reflect 的方法,它允许我们正确地执行 this 绑定,就像这样:

let obj = {     var1: 2,     var2: 3,     sum: 0, } let handlerObj = {     get(target, prop) {         if(prop == 'sum') {             target['sum'] = target['var1'] + target['var2']         }         return Reflect.get(...arguments)     },     set(target, prop, newVal) {         target[prop] = newVal     } } let p = new Proxy(obj, handlerObj) console.log(p.sum)

Vue 3 深入响应性原理

上面我们已经检测到了哪些数据发生了变化,所以接下来我们需要用一个我们还没实现的 track 追踪方法来进行修改:

let obj = {     var1: 2,     var2: 3,     sum: 0, } let track = (target, prop) => {     if(prop == 'sum') {         target['sum'] = target['var1'] + target['var2']     } } let handlerObj = {     get(target, prop) {         track(target, prop)         return target[prop]     },     set(target, prop, newVal) {         target[prop] = newVal     } } let p = new Proxy(obj, handlerObj) console.log(p.sum)

Vue 3 深入响应性原理

最后,当某些内容发生改变时我们会设置新的值。为此,我们将通过触发这些更改来设置新 Proxy 的更改:

let obj = {     var1: 2,     var2: 3,     sum: 0, } let track = (target, prop) => {     if(prop == 'sum') {         target['sum'] = target['var1'] + target['var2']     } } let trigger = (target, prop, newVal) => {     target[prop] = newVal } let handlerObj = {     get(target, prop) {         track(target, prop)         return target[prop]     },     set(target, prop, newVal) {   trigger(target, prop, newVal)                  return Reflect.set(...arguments)     } } let p = new Proxy(obj, handlerObj) console.log(p.sum)

Vue 3 深入响应性原理

  • 当某个值发生变化时进行检测:我们不再需要这样做,因为 Proxy 允许我们拦截它

  • 跟踪更改它的函数:我们在 Proxy 中的 getter 中执行此操作,称为 effect

  • 触发函数以便它可以更新最终值:我们在 Proxy 中的 setter 中进行该操作,名为 trigger

本文分享自微信公众号 - 人生代码(lijinwen1996329ken)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
初识VUE响应式原理
自从Vue发布以来,就受到了广大开发人员的青睐,提到Vue,我们首先想到的就是Vue的响应式系统,那响应式系统到底是怎么回事呢?接下来小编就给大家简单介绍一下Vue中的响应式原理。
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k