VueJS设计与实现之浅响应与深响应详解
正文
前文中讲完了如何响应Object,并处理了一些响应中的问题,但是我们目前,包括之前实现的响应式,其实只是浅响应。
直接上代码
const obj = {a:{b:1}} const reactive = (obj)=> new Proxy(obj,{ get(target,key,receiver){ /*省略其他逻辑*/ return Reflect.get(target,key,receiver) }, /*省略其他拦截*/ }) const data = reactive(obj)
问题就出现在Reflect.get(target, key, receiver)
这句代码里,我们现在尝试一下获取data.a
,应该返回的是{b:1}
,不是Proxy
,自然不会响应什么。
所以对于这种嵌套对象,我们自然要去递归的把对象转换为响应式对象。
const reactive = (obj)=> new Proxy(obj,{ get(target,key,receiver){ /*省略其他逻辑*/ const res = Reflect.get(target,key,receiver) if(res && typeof res === 'object'){ return reactive(res) } return res }, /*省略其他拦截*/ })
这样,当内部是嵌套对象的时候,我们递归把嵌套对象转换为响应式对象,这样再按之前的追踪依赖,触发响应去处理就好了。
当时,深响应和浅响应都是有各自的使用条件的。比如我在完成第一个vue3.2项目有感中写过,我就比较喜欢用shallowRef
,这就是一种浅响应。
好了,话题收回来。我们之前封装的那个reactive已经变成一个深响应了,我们现在就在封装一层,去区分浅响应和深响应。我们通过一个新的参数deepify
去判断浅响应和深响应,然后深响应的时候才去递归。
之所以再封装了一层,是因为我们后续还要继续扩展这个函数
const createReactive = (obj,deepify = true)=>new Proxy(obj,{ get(target,key,receiver){ /*省略其他逻辑*/ const res = Reflect.get(target,key,receiver) //深响应式递归 if(deepify && res && typeof res === 'object'){ return reactive(res) } return res }, /*省略其他拦截*/ })
这样子封装之后,我们就有了2个函数reactive
,shallowReactive
const reactive = (obj)=>createReactive(obj) const shallowReactive = (obj)=>createReactive(obj,false)
大家使用的时候,其实需要看情况去选择,浅响应其实有时候比深响应更方便。就比如我之前在那篇文章中举得例子一样。
以上就是VueJS设计与实现之浅响应与深响应详解的详细内容,更多关于VueJS浅响应深响应的资料请关注我们其它相关文章!
相关推荐
-
vue中provide inject的响应式监听解决方案
目录 provide inject的响应式监听解决 vue监听赋值及provide与inject provide inject的响应式监听解决 提示:provide 和 inject 绑定并不是可响应的.这是刻意为之的.然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的. 所以传值传对象即可 provide(){ return { provObj: { uuidList:{} } } }, this._provided.p
-
Vuejs第一篇之入门教程详解(单向绑定、双向绑定、列表渲染、响应函数)
什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展. 接下来给大家介绍vuejs单向绑定.双向绑定.列表渲染.响应函数基础知识,具体详情如下所示: (一)单向绑定 <div id="app"> {{ message }} </div> <sc
-
代码详解Vuejs响应式原理
响应式原理 > vuejs中的模型(model)和视图(view)是保持同步的,在修改数据的时候会自动更新视图,这其实依赖于Object.defineProperty方法,所以vuejs不支持IE8及以下版本,vuejs通过劫持getter/setter方法来监听数据的变化,通过getter进行依赖收集,在数据变更执行setter的时候通知视图更新. Object.defineProperty > Object.defineProperty可以定义对象的属性或修改对象的属性 > 目前可以
-
vue3结构赋值失去响应式引发的问题思考
目录 前言 原始值的响应式系统的实现 为什么ES6 解构,不能随意使用会破坏他的响应式特性 proxy背景 实现原理 解构 props 对象,因为它会失去响应式 直接赋值reactive响应式对象 vuex中组合API赋值 结语 前言 vue3发布以来经历两年风头正盛,现在大有和react 平分天下的势头,我们知道他是基于proxy 实现响应式的能力, 解决了vue2所遗留下来的一些问题,同时也正由于proxy的特性,也提高了运行时的性能 凡事有利有弊, proxy虽然无敌,但是他也有本身的局限
-
vue3中defineProps传值使用ref响应式失效详解
子组件接收父组件的传参. 父组件: <template> <Son :data="data"/> </template> <script setup> import { ref } from "vue"; let data = ref('hello') setTimeout(() => { data.value = 'how are you doing' }, 2000) </script> 子组件:
-
vuejs响应用户事件(如点击事件)
需求: 页面上的列表原先有3个,我们想点击一次添加一条记录,也可以在头和尾删除数据: 我们也可以删除我们想删除的任意一行记录: 如果是用传统的jquery操作,页面中js会特别多,而且操作也很麻烦. 这里用vue.js就非常简单. 我们先看页面效果: 页面初始化.png 末尾增加一项.png 删除项.png 再来看代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT
-
C++对象的浅复制和深复制详解及简单实例
C++对象的浅复制和深复制详解及简单实例 浅复制:两个对象复制完成后共享某些资源(内存),其中一个对象的销毁会影响另一个对象 深复制:两个对象复制完成后不会共享任何资源,其中一个对象的销毁不会影响另一个对象 下面我们来看一段代码,以便直观的理解: #include<iostream> #include<string.h> using namespace std; class Student { int no; char *pname; public: Student(); Stud
-
VueJS设计与实现之浅响应与深响应详解
正文 前文中讲完了如何响应Object,并处理了一些响应中的问题,但是我们目前,包括之前实现的响应式,其实只是浅响应. 直接上代码 const obj = {a:{b:1}} const reactive = (obj)=> new Proxy(obj,{ get(target,key,receiver){ /*省略其他逻辑*/ return Reflect.get(target,key,receiver) }, /*省略其他拦截*/ }) const data = reactive(obj)
-
基于rem的移动端响应式适配方案(详解)
视口 在前一段时间,我曾经写过一篇关于viewport的文章.最近由于在接触移动端开发,对viewport有了新的理解.于是,打算重新写一篇文章,介绍移动端视口的相关概念. 关于这篇文章说到的所有知识,本质上离不开以下代码 <meta name="viewport" content="width=device-width, initial-scala=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
-
vuejs动态组件给子组件传递数据的方法详解
通过子组件定义时候的props可以支持父组件给子组件传递数据,这些定义的props在子组件的标签中使用绑定属性即可,但是如果使用的是<component>动态组件,这个时候就没有显式的子组件标签,要给子组件传递数据需要在<component> 中进行绑定 <div class="app" id="deviceready"> <component :is="currentView" :user_name.s
-
Vuejs第十一篇组件之slot内容分发实例详解
什么是组件? 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素,Vue.js 的编译器为它添加特殊功能.在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展. Slot分发内容 ①概述: 简单来说,假如父组件需要在子组件内放一些DOM,那么这些DOM是显示.不显示.在哪个地方显示.如何显示,就是slot分发负责的活. ②默认情况下 父组件在子组件内套的内容,是不显示的. 例如代码: <
-
JavaWeb Refresh响应头代码实例详解
这篇文章主要介绍了JavaWeb Refresh响应头代码实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.Refresh响应头:可以理解为定时的重定向,在指定的时间后发生页面的跳转 二.代码示例: package cn.xxx.Servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.Ht
-
Laravel 修改验证异常的响应格式实例代码详解
Laravel 默认验证不通过后响应格式如下,有时此格式并不满足自己要求,需要修改格式. // status 422 { "message":"The given data was invalid.", "errors":{ "url":[ "url 无效的格式" ] } } 当 Request 验证失败时会抛出 ValidationException异常,最终交由全局异常Handler类处理.Handle
-
SpringBoot中的响应式web应用详解
简介 在Spring 5中,Spring MVC引入了webFlux的概念,webFlux的底层是基于reactor-netty来的,而reactor-netty又使用了Reactor库. 本文将会介绍在Spring Boot中reactive在WebFlux中的使用. Reactive in Spring 前面我们讲到了,webFlux的基础是Reactor. 于是Spring Boot其实拥有了两套不同的web框架,第一套框架是基于传统的Servlet API和Spring MVC,第二套是
-
java面向对象设计原则之单一职责与依赖倒置原则详解
目录 单一职责概念 实现 拓展 依赖倒置原则概念 示例 拓展 单一职责概念 不要存在多于一个导致类变更的原因,也就是说每个类应该实现单一的职责,否则就应该把类拆分.交杂不清的职责将使得代码牵一发而动全身,导致代码混涩难懂,不易修改.难以扩展和复用.如:以前开发C/S程序中的胖客户端程序,就是将人机交互逻辑.业务加工处理逻辑和数据库操作逻辑混合在一起. 实现 单一职责原则是进行类的划分和封装的基本原则,进行类的具体抽象.尽量做到,类的功能单一和清晰化. 1.根据机能划分,使用封装来创建对象之间的分
-
Vue3 Reactive响应式原理逻辑详解
目录 前言 一.怎么实现变量变化 二.怎么实现变量变化 三.将多个dep存储在Map中 四.将多个object的depsMap继续存储起来 五.核心 六.源码解析(TypeScript) 前言 本篇文章主要讲解vue响应式原理的逻辑,也就是vue怎么从最开始一步步推导出响应式的结构框架. 先从头构建一个简单函数推导出Vue3的Reactive原理,最后再进行源码的验证. 一.怎么实现变量变化 怎么实现变量变化,相关依赖的结果也跟着变化 当原本price=5变为price=20后total应该变为
随机推荐
- 理解Javascript文件动态加载
- SQL Server附加数据库出错,错误代码5123
- 详谈Angular路由与Nodejs路由的区别
- 用Java将字符串的首字母转换大小写
- 轻松掌握java责任链模式
- ASP.NET实现图片以二进制的形式存入数据库
- 深入理解Asp.Net中WebForm的生命周期
- .net实现ping的实例代码
- asp.net(c#)下各种进制间的轻松转换(2进制、8进制、10进制、16进制)
- Microsoft VBScript 编译器错误 错误原因 代码大全
- 多字段模糊搜索的函数
- servlet上传文件实现代码详解(四)
- javascript cookie用法基础教程(概念,设置,读取及删除)
- php实现微信扫码支付
- 关于图片的预加载过程中隐藏未知的
- mysql 字符集的系统变量说明
- Google关键词广告基础知识问答
- java 整型数与Integer的缓存深入理解
- php数组一对一替换实现代码
- Android RecyclerView的焦点记忆封装