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中也会随之更新

image

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中也会随之更新

image

4. 参考资料

[1] Proxy - JavaScript | MDN (mozilla.org)

[2] Object.defineProperty() - JavaScript | MDN (mozilla.org)

posted @ 2023-07-23 00:37  当时明月在曾照彩云归  阅读(249)  评论(0)    收藏  举报