Vue3如何实现响应式

回顾Vue2.x的Object.define Property

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

学习proxy语法

基本使用

javascript 复制代码
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实现响应式

废话不多说,直接上代码

javascript 复制代码
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。

相关推荐
XIE3924 分钟前
TipKit:开源富文本编辑器套件,一套逻辑,任意风格!
前端·笔记·开源
范什么特西18 分钟前
一些常用名词
开发语言·前端·javascript
晴天1620 分钟前
前端打包工具全景解析
前端
晴天1621 分钟前
Vite vs Webpack 全方位对比
前端·webpack·node.js
体毛旺盛的猿24 分钟前
HarmonyOS开发面试题
前端·华为·harmonyos
anOnion38 分钟前
构建无障碍组件之Landmarks Pattern
前端·html·交互设计
牧瀬クリスだ39 分钟前
前端三件套基础之JS!!!!
前端·javascript
乌夷42 分钟前
JavaScript 的事件循环
开发语言·javascript·ecmascript
风骏时光牛马42 分钟前
提示词工程:大模型交互的核心塑造技术
前端
单线程_011 小时前
从案例分析 Vue3 Tokenizer+Parser 源码四
前端·javascript·vue.js