vue响应式原理

响应式原理步骤:
1、封装对象响应式defineReactive函数(步骤:① 递归 ② Object.defineProperty())
2、数组的响应式(数组方法重写)
① 将数组原型保存出来Array.prototype
② 复制一份数组的原型,用来进行数组方法的重写,防止污染原有的数组原型Object.create()
③ 枚举所有数组方法,将数组方法进行重写
3、封装监听observer函数,监听某些数据的变化,判断监听的是数组还是对象,步骤:
对象:
①枚举对象,调用defineReactive
数组:
①将数组的__proto__属性指向重写后的原型
4、渲染函数到页面render()


```javascript
        const data = {
            name: "wuying",
            age: 18,
            looks: {
                look: "beauty"
            },
            arr: [1, 2, 3]
        }
        /*
        1、
          data:监听的对象
          key:监听的某个属性名
          value:该属性名对应的属性值
        */
        function defineReactive(data, key, value) {
            observer(value)//递归从而可以监听子对象子子对象等
            Object.defineProperty(data, key, {
                get() {
                    return value
                },
                set(newValue) {
                    value = newValue
                    render()
                }
            })
        }
        /*
        2、
        ① 将数组原型保存出来
        ② 复制一份数组的原型,用来进行数组方法的重写,防止污染原有的数组原型
        ③ 枚举所有数组方法,将数组方法进行重写
        */
       const saveObjectPro = Array.prototype
       const copyPrototype = Object.create(saveObjectPro)
       ['pop','push','shift','unshift','sort','splice','resverse'].forEach(method => {
           copyPrototype[method] = function () {
               saveObjectPro[method].call(this,...arguments)
               render()
           }
       });
        /*
        3、
           data:监听的对象
        */
        function observer(data) {
            /*
                1、判断data是对象或者数组
                对象:①枚举对象,调用defineReactive
                数组:将数组的__proto__属性指向重写后的原型
            */
            if (Array.isArray(data)) {
                data.__proto__ = copyPrototype
                return;
            }
            if (typeof data === 'object') {
                for (const key in data) {
                    defineReactive(data, key, data[key])
                }
            }
        }
        /*
        4、渲染函数
        */
        function render() {
            console.log("这里会经过渲染操作,即完成页面的渲染")
        }
        observer(data)
## 扩展:`$set`和`$delete`如何实现
```javascript
function _$set(data,key,value) {
            if (Array.isArray(data)) {
                data.splice(key,1,value)
                return value
            }
            defineReactive(data,key,value)
            render()
            return value
        }

        function _$delete(data,key) {
            if (Array.isArray(data)) {
                data.splice(key,1)
                return ;
            }

        delete data[key]
            render()
        }

以上是vue2.0响应数据原理,vue3.0使用proxy实现,后序会继续更新…
总结:使用Object.defineProperty实现响应式的劣势
1、无法监听数组不存在的索引的变化
2、无法监听数组长度的变化
3、无法监听对象的增删
4、天生就需要进行递归

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值