vue3响应式原理

  • 回顾vue2Object.defineProperty

  • 缺点

    • 深度监听对象需要一次性递归
    • 无法监听新增属性、删除属性(Vue.setVue.delete)
    • 无法监听原生数组,需要特殊处理
  • 学习proxy语法

  • Vue3中如何使用proxy实现响应式

Proxy 基本使用

js 复制代码
// const data = {
//     name: 'zhangsan',
//     age: 20,
// }
const data = ['a', 'b', 'c']

const proxyData = new Proxy(data, {
    get(target, key, receiver) {
        // 只处理本身(非原型的)属性
        const ownKeys = Reflect.ownKeys(target)
        if (ownKeys.includes(key)) {
            console.log('get', key) // 监听
        }

        const result = Reflect.get(target, key, receiver)
        return result // 返回结果
    },
    set(target, key, val, receiver) {
        // 重复的数据,不处理
        if (val === target[key]) {
            return true
        }

        const result = Reflect.set(target, key, val, receiver)
        console.log('set', key, val)
        // console.log('result', result) // true
        return result // 是否设置成功
    },
    deleteProperty(target, key) {
        const result = Reflect.deleteProperty(target, key)
        console.log('delete property', key)
        // console.log('result', result) // true
        return result // 是否删除成功
    }
})

vue3响应式原理

深度监听,性能更好(获取到哪一层才触发响应式get,不是一次性递归)

可监听新增/删除属性

可监听数组变化

javascript 复制代码
// 创建响应式
function reactive(target = {}) {
    if (typeof target !== 'object' || target == null) {
        // 不是对象或数组,则返回
        return target
    }

    // 代理配置
    const proxyConf = {
        get(target, key, receiver) {
            // 只处理本身(非原型的)属性
            const ownKeys = Reflect.ownKeys(target)
            if (ownKeys.includes(key)) {
                console.log('get', key) // 监听
            }
    
            const result = Reflect.get(target, key, receiver)
        
            // 深度监听
            // 性能如何提升的?获取到哪一层才触发响应式get,不是一次性递归
            return reactive(result)
        },
        set(target, key, val, receiver) {
            // 重复的数据,不处理
            if (val === target[key]) {
                return true
            }
    
            const ownKeys = Reflect.ownKeys(target)
            if (ownKeys.includes(key)) {
                console.log('已有的 key', key)
            } else {
                console.log('新增的 key', key)
            }

            const result = Reflect.set(target, key, val, receiver)
            console.log('set', key, val)
            // console.log('result', result) // true
            return result // 是否设置成功
        },
        deleteProperty(target, key) {
            const result = Reflect.deleteProperty(target, key)
            console.log('delete property', key)
            // console.log('result', result) // true
            return result // 是否删除成功
        }
    }

    // 生成代理对象
    const observed = new Proxy(target, proxyConf)
    return observed
}

// 测试数据
const data = {
    name: 'zhangsan',
    age: 20,
    info: {
        city: 'shenshen',
        a: {
            b: {
                c: {
                    d: {
                        e: 100
                    }
                }
            }
        }
    }
}
const proxyData = reactive(data)
相关推荐
这儿有一堆花14 分钟前
网站链接重定向原理
前端
麦麦大数据22 分钟前
F029 vue游戏推荐大数据可视化系统vue+flask+mysql|steam游戏平台可视化
vue.js·游戏·信息可视化·flask·推荐算法·游戏推荐
cecyci22 分钟前
如何实现AI聊天机器人的打字机效果?
前端·javascript
IT_陈寒26 分钟前
Vite 5个隐藏技巧让你的项目构建速度提升50%,第3个太香了!
前端·人工智能·后端
詩句☾⋆᭄南笙34 分钟前
HTML的盒子模型
前端·html·盒子模型
落言36 分钟前
AI 时代的工程师:懂,却非懂的时代
前端·程序员·架构
一枚攻城狮38 分钟前
前端知识点大汇总
前端
paopaokaka_luck1 小时前
基于SpringBoot+Vue的社区诊所管理系统(AI问答、webSocket实时聊天、Echarts图形化分析)
vue.js·人工智能·spring boot·后端·websocket
余道各努力,千里自同风2 小时前
el-input 输入框宽度自适应宽度
javascript·vue.js·elementui
Mike_jia2 小时前
DumbAssets:开源资产管理神器,家庭与企业的高效管家
前端