vue的响应式原理及从无到有用原生js实现vue的一套响应式系统

本文探讨Vue的响应式原理,通过Object.defineProperty实现数据代理,解释如何通过get和set监听属性变化,以及如何处理数组变异方法。并介绍了如何构建一个简单的响应式系统,包括属性追踪、异步更新队列和避免不必要的DOM更新。
摘要由CSDN通过智能技术生成

what is 响应式?

响应式作为vue的代表特点之一, 意义非凡, 响应式的含义也就是: 我们更改了js中的数据, 页面会同步进行更新, 同理, 页面中的数据发生了变化, js也会得到通知从而更改数据

来看看实例

<!-- html结构相当的简单, 一个id为app的div, 之后我们会让vue来接管该div -->
<div id='#app'></div>
const vm = new Vue({
   
    el: '#app',
    data: {
   
        msg: 'helloWorld'
    }
})

当我们在页面中直接通过控制台更改vue实例上的msg属性的时候, 其实页面也同步渲染了, 这就是响应式, 如下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h50TuXii-1591941872056)(./响应式.gif)]

how to do 响应式?

可能很多朋友都或多或少的了解过vue的响应式是通过Object.defineProperty实现的, 响应式系统的核心原理确实是如此, 但是远不止于此, 话不多说, 我们从最基本的Object.defineProperty来看看vue优等生的完美作业之响应式系统

笔者也是自己的学习和领悟, 希望多多交流, 如有问题请及时指出

  • Object.defineProperty

    这哥们用来给一个对象进行代理, 当我们对一个对象进行代理以后, 那么对这个对象进行任何的访问都将得到监控

    在现实中, 我们可以理解为明星艺人和经纪人的关系, 当有经纪人为艺人进行代理业务以后, 以后每一个跟艺人相关的操作和业务都会被经纪人监控到, 经纪人也可以选择是否让艺人来承接这个业务或者参加某个活动等, 如果你还是不太理解, 那么我们来看看实例, 我相信你会对Object.defineProperty更加的明白

    // 我们实际上是要在用户修改某个属性的时候, 我们要得到通知, 就这么简单
    let pengyuyan = {
         
        name: '彭于晏',
        address: '地球的某个地方'
    }
    
    pengyuyan.address =  '台湾';
    

    像上面这样操作我们能够得到通知吗? 答案是否定的, 因为更改属性一瞬间就发生了, 我们都妹机会来捕捉他的变化, 所以我们来看看如下这样写

    let pengyuyan = {
         
        name: '彭于晏',
        address: '地球的某个地方'
    }
    
    let pengyuyanName = pengyuyan.name;
    Object.defineProperty(pengyuyan, 'name', {
         
        get() {
         
            console.log('有人要找彭于晏啦, 快看看是不是吴彦祖');
            return pengyuyanName;
        },
        set(newVal) {
         
            console.log('有人要改彭于晏的名字啦, 快点来人看看在他改名字之前我们是不是要做点什么啊');
            pengyuyanName = newVal;
        }
    })
    

    Object.defineProperty给某个对象的某个属性进行代理以后, 会给该对象的被代理属性提供一个getset方法, get用来监控之后任何操作对于被代理属性的访问, set用来监控之后任何操作对于被代理属性的修改

    于是当我们对pengyuyan对象的name的属性进行读和写的时候, 会在读和写的时候得到提示获得一定的反馈, 如下图

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oXxKbbKW-1591941872058)(./pengyuyan.gif)]

    于是乎, 我们便可以用我们的方式来模拟一下vue的响应式

    <!-- 这是一开始页面中渲染的内容, 我们要做的就是当js的数据改变的时候页面要相应的给予反馈 -->
    <div id='#app'>
    </div>
    
    const pengyuyan =  (function () {
         
        const app = document.getElementById('app');
        const pengyuyan = {
         
            name: 'pengyuyan',
            age: 18
        }
    
        function init() {
         
            render(pengyuyan.name);
            observer();
        }
    
        // 负责渲染的函数
        function render(value) {
         
            app.innerHTML = value;
        }
    
        function observer() {
         
            // 代理
            let pengyuyanName = pengyuyan.name;
            Object.defineProperty(pengyuyan, 'name', {
         
                get() {
         
                    return pengyuyanName;
                },
    
                set(newVal) {
         
                    pengyuyanName = newVal;
                    render(pengyuyanName);
                }
            })
        }
    
        init();
    
        return pengyuyan;
    }())
    

    上面的代码其实写的非常的简单, 如果你看不懂的话笔者建议你补一补js的基础知识,

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值