JavaScript自定义响应式对象
1. 引言
这里的响应式对象是指JavaScript中的变量与HTML中的内容相绑定,变量更新则内容更新,也叫数据绑定
此时不得不说MVVM架构,MVVM架构思想的实现步骤如下:
- 模型(Model):负责处理数据的读写操作,包括从服务器获取数据、存储数据等
- 视图(View):负责渲染用户界面,包括HTML、CSS和JavaScript等,但不包括业务逻辑
- 视图模型(ViewModel):连接视图和模型的桥梁,负责从模型中获取数据,并将其转换为视图可以使用的格式,同时也负责将视图中的用户交互事件转换为模型可以理解的操作。视图模型中不包含任何与视图相关的代码,从而实现了解耦
响应式对象或者说数据绑定,是视图模型(VM)的核心,只需改变JS中的变量的内容(修改Model),HTML中的内容也会随之变化(视图变化)
MVVM框架很多,典型如Vue、React等
以下记述的是自定义一个响应式对象,分别是使用JavaScript的Object.defineProperty方法和Proxy对象来实现
2. Proxy
Proxy 是ES6中的对象用于创建一个对象的代理,从而实现对对象的操作的拦截,基础用法为const p = new Proxy(target, handler),更为详细的文档可以参考MDN:Proxy - JavaScript | MDN (mozilla.org)
使用Proxy对象是Vue3响应式的实现方法
自定义一个响应式对象,此处的思路也很简单,就是使用Proxy对象来代理目标对象,然后设置handler.set()方法,实现目标对象的赋值拦截并更新DOM
示例代码如下:
<body>
<div id="container"></div>
<script>
function reactive(obj) {
const handler = {
get(target, key) {
return Reflect.get(target, key)
},
set(target, key, value) {
if (key === 'value')
document.getElementById('container').innerHTML = value
return Reflect.set(target, key, value)
}
}
return new Proxy(obj, handler)
}
const obj = reactive({})
</script>
</body>
此时,设置obj.value = <new value>,DOM中也会随之更新

3. Object.defineProperty
Object.defineProperty() 静态方法会直接在一个对象上定义一个新属性,或修改其现有属性,并返回此对象,其基本语法为Object.defineProperty(obj, prop, descriptor),其中descriptor表示要定义或修改的属性的描述符,可以设置 getter 和 setter 的函数,更为详细的文档可参考MDN:Object.defineProperty() - JavaScript | MDN (mozilla.org)
使用Object.defineProperty方法是Vue2响应式的实现方法
自定义一个响应式对象,此处的思路也很简单,就是使用Object.defineProperty来给目标对象设置属性,然后设置setter 函数方法,实现目标对象的赋值拦截并更新DOM
示例代码如下:
<body>
<div id="container"></div>
<script>
function reactive(obj) {
return Object.defineProperty(obj, 'value', {
get() {
return this._value
},
set(value) {
this._value = value
document.getElementById('container').innerHTML = value
}
})
}
const obj = reactive({})
</script>
</body>
此时,设置obj.value = <new value>,DOM中也会随之更新

4. 参考资料
[1] Proxy - JavaScript | MDN (mozilla.org)
[2] Object.defineProperty() - JavaScript | MDN (mozilla.org)
JavaScript自定义响应式对象的更多相关文章
- 由浅入深,带你用JavaScript实现响应式原理(Vue2、Vue3响应式原理)
由浅入深,带你用JavaScript实现响应式原理 前言 为什么前端框架Vue能够做到响应式?当依赖数据发生变化时,会对页面进行自动更新,其原理还是在于对响应式数据的获取和设置进行了监听,一旦监听到数 ...
- 读Vue源码二 (响应式对象)
vue在init的时候会执行observer方法,如果value是对象就直接返回,如果对象上没有定义过_ob_这个属性,就 new Observer实例 export function observe ...
- 二、vue响应式对象
Object.defineProperty Object.defineProperty 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象,先来看一下它的语法: Obj ...
- Vue.set 向响应式对象中添加响应式属性,及设置数组元素触发视图更新
一.为什么需要使用Vue.set? vue中不能检测到数组和对象的两种变化: 1.数组长度的变化 vm.arr.length = 4 2.数组通过索引值修改内容 vm.arr[1] = ‘aa’ Vu ...
- Vue3中的响应式对象Reactive源码分析
Vue3中的响应式对象Reactive源码分析 ReactiveEffect.js 中的 trackEffects函数 及 ReactiveEffect类 在Ref随笔中已经介绍,在本文中不做赘述 本 ...
- JavaScript辅助响应式
js响应式 rem辅助响应式布局:其实就是指在HTML页面的大小不断变化的时候,里面的宽.高.字体等等也随之变化,主要是通过获取window.innerwidth的值来进行判断,7.5rem===10 ...
- JavaScript自定义类和对象的方法
备注:JavaScript中没有类class的概念,一般把原型对象看作类 1. 工厂方法--使用new Object创建对象并添加相关属性 var Obj = new Object; ...
- Javascript之响应式相册
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...
- javascript自定义简单map对象功能
这里介绍一种js创建简单map对象的方法: function Map() { //创建object对象, 并给object对象添加key和value属性 var obj1=new Object(); ...
- vue2.0与3.0响应式原理机制
vue2.0响应式原理 - defineProperty 这个原理老生常谈了,就是拦截对象,给对象的属性增加set 和 get方法,因为核心是defineProperty所以还需要对数组的方法进行拦截 ...
随机推荐
- 借助Rich库实现Pandas DataFrame颜值升级
pandas的DataFrame功能强大自不必说,它可以帮助我们极大的提高统计分析的效率. 不过,使用DataFrame开发我们的分析程序的时候,经常需要打印出DataFrame的内容,以验证和调试数 ...
- Spring Boot + MyBatis-Plus 实现 MySQL 主从复制动态数据源切换
MySQL 主从复制是一种常见的数据库架构,它可以提高数据库的性能和可用性.动态数据源切换则可以根据业务需求,在不同场景下使用不同的数据源,比如在读多写少的场景下,可以通过切换到从库来分担主库的压力. ...
- 【开工大吉】推荐4款开源、美观的WPF UI组件库
前言 经常有小伙伴在技术群里提问:WPF有什么好用的UI组件库?,今天大姚给大家推荐4款开源.美观的WPF UI组件库. WPF介绍 WPF 是一个强大的桌面应用程序框架,用于构建具有丰富用户界面的 ...
- 如何从零实现属于自己的 API 网关?
序言 上一篇文章:你连对外接口签名都不会知道?有时间还是要学习学习. 有很多小伙伴反应,对外的 API 中相关的加签,验签这些工作可以统一使用网关去处理. 说到网关,大家肯定比较熟悉.市面上使用比较广 ...
- spring boot 2.0集成并使用redis
项目地址:https://gitee.com/indexman/spring_boot_in_action 前面一章介绍了spring boot自带的缓存,下面讲一下如何在2.0版本中集成并使用red ...
- String--getline()
#include <string> #include <sstream> #include <iostream> int main() { std::wstring ...
- 发送HTML模板邮件
概述 为了增强邮件内容展示的样式,可以将普通的文本邮件转换为HTML内容格式. 在Java中,可以通过页面模板技术来实现.具体来说,可以使用Thymeleaf模板. 具体实现 首先,在项目中引入Thy ...
- rpartition和partition按分割符分割
# rpartition 从目标字符串的末尾也就是右边开始搜索分割符,如果字符串包含指定的分割符 则返回一个3元的元组,第一个为分割符左边的子串,第二个为分割符本身, 第三个为分割符右边的字串. st ...
- python中操作csv
示例 import csv with open('t.csv', mode='r', encoding='utf-8') as f: reader_obj = csv.reader(f) # 通过re ...
- day05---系统的重要文件(3)
1) /usr/local 编辑 安装的软件 第三方软件安装位置 软件安装的三种方法 1.yum安装 自动解决依赖问题 yum [选项参数] 包名 第一个里程碑:我想要安装的软件的名字 或者是 知道命 ...