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所以还需要对数组的方法进行拦截 ...
随机推荐
- Flink CDC实时同步PG数据库到Kafka
一.安装规划 操作系统 服务器IP 主机名 硬件配置 CentOS7.6 192.168.80.131 hadoop01 内存:2GB,CPU:2核,硬盘:100GB CentOS7.6 192.16 ...
- Linux-find命令报错: missing argument to `-exec'
报错提示:find: missing argument to `-exec' 今天写一个清理脚本,用到了find命令.本来是这么写的: find . -type f -mtime +7 -name & ...
- python-比较两个列表中的相同元素和不同元素
由于两个列表(List)中可能会存在重复的元素,所以我们可以将列表转化成集合(set)进行去重,然后计算交集和差集. A = ['1','2','3'] B = ['2','4','5'] ##计算交 ...
- 剑指Offer07 重建二叉树
剑指 Offer 07. 重建二叉树 前置概念: 前序:访问根节点,先序遍历左子树,先序遍历右子树: 中序:中序遍历左子树,访问根节点,中序遍历右子树: 后序:后序遍历左子树,后序遍历右子树,访问根节 ...
- typescript 实现enum枚举值定义为对象
壹 ❀ 引 最近因为有一些闲散时间,所以一直在做将Class组件重构为typescript + hooks组件的工作,结果今天就遇到一个有趣的问题.我们知道react Class组件一般都会定义Com ...
- P2P通讯方式
概述 实现p2p通讯我们提供两种方式,这两种方式分别是通过客户端直接互通和p2p映射: 无论哪一种,首先设备两端都得部署好fastnat客户端,NAT类型不能是对称类型NAT(Symmetric),否 ...
- Jenkins共享库使用
简单使用 共享库(Shared libraries)是一种可以用来封装函数.变量甚至整个 Pipeline 的机制.通过共享库,可以将常用的功能和流程逻辑定义在单独的 Groovy 脚本中,然后在多个 ...
- python模块imghdr-----推测图像类型
官方文档 https://docs.python.org/zh-cn/3/library/imghdr.html#module-imghdr 用处 模块推测文件或字节流中的图像的类型 imghdr.w ...
- Java 设计模式----单例模式--饿汉式
1 package com.bytezreo.singleton; 2 3 /** 4 * 5 * @Description 单例设计模式 例子-----饿汉式 6 * @author Bytezer ...
- C++ //类模板与函数模板的区别 //1.类模板没有自动类型推导的使用方式 //2.类模板子模板参数中可以有默认参数
1 //类模板与函数模板的区别 2 //1.类模板没有自动类型推导的使用方式 3 //2.类模板子模板参数中可以有默认参数 4 5 #include <iostream> 6 #inclu ...