Vue3如何实现响应式

回顾Vue2.x的Object.define Property

关于vue2的响应式实现可以看下我的另一篇文章:vue2响应式的实现一机Object.defineProperty的缺点

学习proxy语法

基本使用

const data = {
    a: 1,
    b: '20',
    c: [1, 2, 3]
}

const proxyData = new Proxy(data, {
    get(target, key, receiver) {
        // 只处理本身(非原型)数据
        if (Reflect.ownKeys(target)) {
            console.log('keys', Reflect.ownKeys(target));
        }
        const result = Reflect.get(target, key, receiver);
        console.log('get', key);
        return result;
    },
    set(target, key, value, receiver) {
        // 重复数据,不处理
        const oldValue = target[key];
        if (oldValue === value) {
            return true;
        }
        console.log('set', key, value)
        const result = Reflect.set(target, key, value, receiver);
        return result;
    },
    deleteProperty(target, key) {
        console.log('delete', key)
        const result = Reflect.deleteProperty(target, key);
        return result;
    }
})

Reflect

  • 和proxy能力一一对应
  • 规范化、标准化、函数式
  • 代替Object上的工具函数

实现响应式

Vue如何用proxy实现响应式

废话不多说,直接上代码

const data = {
    a: 1,
    b: '20',
    c: {
        d: {
            e: [1, 2, 3]
        }
    },
    info: {
        name: 'wenrenfangge'
    }
}

function reactive(target = {}) {
    if (target == null || typeof target !== "object") {
        return target;
    }
    const config = {
        get(target, key, receiver) {
            // 只处理本身(非原型)数据
            const ownKeys = Reflect.ownKeys(target)
            if (ownKeys.includes(key)) {
                console.log('已有的key:', key);
            } else {
                console.log('新增的key:', key);
            }
            const result = Reflect.get(target, key, receiver);
            console.log('get', key);
            return reactive(result);
        },
        set(target, key, value, receiver) {
            // 重复数据,不处理
            const oldValue = target[key];
            if (oldValue === value) {
                return true;
            }
            if (ownKeys.includes(key)) {
                console.log('已有的key:', key);
            } else {
                console.log('新增的key:', key);
            }
            console.log('set', key, value)
            const result = Reflect.set(target, key, value, receiver);
            return result;
        },
        deleteProperty(target, key) {
            console.log('delete', key)
            const result = Reflect.deleteProperty(target, key);
            return result;
        }
    }
    return new Proxy(target, config);
}

const proxyData = reactive(data);
  • 深度监听,性能更好
  • 可监听新增/删除属性
  • 可监听数组变化

Proxy能规避Object.defineProperty的问题,但是无法兼容所有浏览器,无法polyfill。

相关推荐

  1. Vue3如何实现响应

    2024-07-22 15:06:02       20 阅读
  2. Vue3实现响应编程

    2024-07-22 15:06:02       44 阅读
  3. VUE3-响应

    2024-07-22 15:06:02       50 阅读
  4. Vue3:ref和reactive实现响应数据

    2024-07-22 15:06:02       37 阅读
  5. vue3 原理【详解】Proxy 实现响应

    2024-07-22 15:06:02       33 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-22 15:06:02       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-22 15:06:02       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-22 15:06:02       45 阅读
  4. Python语言-面向对象

    2024-07-22 15:06:02       55 阅读

热门阅读

  1. Dirb目录扫描器

    2024-07-22 15:06:02       18 阅读
  2. C. Mad MAD Sum(cf960)

    2024-07-22 15:06:02       17 阅读
  3. 【数据治理】数据治理:数据质量关键技术

    2024-07-22 15:06:02       18 阅读
  4. nginx虚拟主机配置项

    2024-07-22 15:06:02       17 阅读
  5. 在 CentOS 7 上编译安装 Python 3.11

    2024-07-22 15:06:02       14 阅读
  6. 算法学习3——搜索算法

    2024-07-22 15:06:02       17 阅读
  7. IaaS是什么的简称?关于IaaS的介绍

    2024-07-22 15:06:02       18 阅读
  8. [C++]——常见内存泄漏场景

    2024-07-22 15:06:02       16 阅读