Vue数据监听Object.definedProperty()方法的实现

简介: Vue数据监听Object.definedProperty()方法的实现

Object.definedProperty()

1. 基本方法

    let book = {};
    Object.definedProperty(book, 'name', {
      value: 'John',
      writable: false,
      configurable: false,
      enumerable: false,
      get() {
        return newValue;
      },
      set(newValue) {
        book.name = newValue;
      },
    });

    2. 属性作用

    value:为当前设定的对象book的属性name的值,此处也可以设定默认值。
    如果不设定默认为
    undefined

    writable:能否修改对象book的属性name的值。

    true: 代表当前的值可通过赋值的方式(见下文)属性重定义的方式(见下文)的方式可进行修改

    false: 和 true 的情况相反,也就是不能修改对象的属性的值

    configurable:表示当前对象的属性能否被删除。

    true: 可以删除对象的属性

    false: 不能删除对象的属性

    enumerable: 定义道德对象的属性是否可以在 for...in 循环和 Object.keys() 中进行遍历。

    (1) value 属性


    let person = {};
    //  赋值的方式
    person.name = 'rose';
    //  属性重定义的方式
    Object.defineProperty(person, 'name', {
               value: 'jack',
    });

    (2) writable 属性


    // 情况一:writable: false
    let person = {};
    Object.defineProperty(person, 'name', {
      value: 'jack',
      writable: false,
    });
    person.name = 'rose';
    console.log('赋值方式person.name', person.name); //  jack
    Object.defineProperty(person, 'name', {
      value: 'jack',
      writable: false,
    });
    console.log('属性重定义方式person.name', person.name); //  jack
    // 情况二:writable: true
    let person = {};
    Object.defineProperty(person, 'name', {
      value: 'jack',
      writable: true,
    });
    person.name = 'rose';
    console.log('赋值方式person.name', person.name); //  rose
    Object.defineProperty(person, 'name', {
      value: 'john',
    });
    console.log('属性重定义方式person.name', person.name); //  john

    (3)configurable 属性


    // 情况一:configurable: false
    let person = {};
    Object.defineProperty(person, 'name', {
      value: 'jack',
      configurable: false,
    });
    delete person.name;
    console.log('🚀person', person); // person {name: jack}
    // 情况二:configurable: true
    let person = {};
    Object.defineProperty(person, 'name', {
      value: 'jack',
      configurable: true,
    });
    delete person.name;
    console.log('🚀person', person); // person {}

    (4) enumerable 属性


    let person = {};
    Object.defineProperty(person, 'name', {
      value: 'jack',
      enumerable: true,
    });
    person.gender = 'man';
    Object.defineProperty(person, 'age', {
      value: '26',
      enumerable: false,
    });
    console.log(Object.keys(person)); // [0:'name',1:'gender']
    for (const key in person) {
      console.log(key);
    } // name gender

    (5) get()方法

    属性的 getter 函数,如果没有 getter ,则为 undefined。当访问改属性时,会调用此函数,
    执行时不需要传入任何参数,但是默认会传入
    this 对象(由于继承关系,这里的 this 指向的 this
    指向不一定是定义改属性的对象)。该函数的返回值会被用作该属性的值。

    (6) set() 方法

    属性的 setter 函数,如果没有 setter ,则为 undefined。当属性值被修改时,会调用此函数。该
    方法接受一个参数(也就是被赋予的新值),会传入赋值的
    this 对象。

    3. 原理实现

    在 MVVM 框架中,一是监听数据的变化,二是数据驱动。

    在通常使用中我们使用 Object.definedProperty() 来实现监听数据的变化,或者使用 Proxy 和 反射。

    本章通过使用 MutationObserver 来实现 Object.definedProperty() 对数据变化的监听。

    (1) API 的使用

    定义:MutationObserver 构造函数对 DOM 树所做的更改提供了监听的能力。替代了旧的 MutaionEvents
    功能。

    返回值:MutationObserver 创建后并返回一个 new MutationObserver,当 DOM 发生改变时,会调用
    制定的回调函数。

    注意点:

    MutationObserver API 是异步触发的,DOM 的改变并不会马上触发,而是等到所有对 DOM 改变的操作
    完成后,整体的触发一次。

    面对多次的 DOM 修改,MutationObserver 会将多次的改变记录封装成一个数组进行处理,而不是一条
    一条进行处理。

    MutationObserver 在不影响浏览器性能的情况下响应 DOM 的更改。

    基本方法:

    disconnect():停止 MutationObserver 的监听,直到再次 observe() 再次被调用。

    observe():开始监听,并通过回调函数让 MutationObserver 接受通知。

    takeRecords():从 MutationObserver 的通知队列中移除所有挂起的通知,并在一个新Array
    MutationObserver 对象中返回它们。

    (2) 代码实现


    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Object.definedProperty的实现</title>
      </head>
      <body>
        <div id="app">
          <h1 id="h"></h1>
        </div>
      </body>
    </html>
    <script>
      // 选择要观察的节点
      const targetNode = document.getElementById('app');
      // 具体要观察节点那些改变
      const config = { attributes: true, childList: true, subtree: true };
      // 创建一个回调函数的实例,节点发生改变时执行的回调函数
      const Observer = new MutationObserver((mutationList, observer) => {
        mutationList.forEach((item, index) => {
          if (item.type === 'childList') {
            console.log('有节点发生改变,当前节点的内容是:', item.target.innerHTML);
          } else if (item.type === 'attributes') {
            console.log('修改了' + item.attributeName + '属性');
          }
        });
      });
      // 开始观察节点是否发生变化
      Observer.observe(targetNode, config);
      // 停止观察
      // observer.disconnect();
    </script>


    (3) 输出结果

    相关文章
    |
    12天前
    |
    监控 JavaScript 前端开发
    使用Vue.js开发员工上网行为监控的实时数据展示页面
    使用Vue.js开发的实时员工上网行为监控页面,展示员工访问的网站、应用和时间等数据。页面响应式设计,适应不同设备。通过Vue组件显示实时数据,如`&lt;li v-for=&quot;activity in activities&quot;&gt;`循环渲染。数据定时更新,利用Vue的生命周期钩子和axios从服务器获取并自动刷新,确保数据的时效性。该页面有助于管理者即时了解员工网络活动,保障企业网络安全和资源管理。
    63 5
    |
    12天前
    |
    Java API
    API:object当中的各种方法刨析(今日份:equals toString)
    API:object当中的各种方法刨析(今日份:equals toString)
    |
    13天前
    |
    JavaScript Java 测试技术
    基于springboot+vue.js+uniapp小程序的共享单车数据存储系统附带文章源码部署视频讲解等
    基于springboot+vue.js+uniapp小程序的共享单车数据存储系统附带文章源码部署视频讲解等
    11 1
    |
    14天前
    |
    JavaScript
    vue数据的双向绑定
    vue数据的双向绑定
    |
    19天前
    |
    JavaScript
    |
    7天前
    |
    缓存 监控 JavaScript
    Vue.js中的计算属性 computed 与监听属性 watch深入探索
    Vue.js中的计算属性 computed 与监听属性 watch深入探索
    28 0
    |
    8天前
    |
    JavaScript 前端开发 测试技术
    Map 和 Object 在处理大量数据时性能差异
    Map 和 Object 在处理大量数据时性能差异
    |
    1月前
    |
    JavaScript
    Vue : Object.defineProperty()
    Vue : Object.defineProperty()
    25 2
    |
    1月前
    |
    前端开发 JavaScript
    前端 js 经典:Object 常用原生方法
    前端 js 经典:Object 常用原生方法
    59 2
    |
    18天前
    |
    Java API
    JavaSE——常用API进阶一(1/3)-Object类(Object类的作用、Object类的常见方法-toString方法、equal方法、clone方法)
    JavaSE——常用API进阶一(1/3)-Object类(Object类的作用、Object类的常见方法-toString方法、equal方法、clone方法)
    13 0