手把手带你敲vue2 reactive 响应式原理

40 篇文章 2 订阅

vue2响应式原理:核心使用Object.defineProperty给属性定义get和set方法
注意:对象的多次递归,针对数组需要重写数组方法

函数劫持:把函数内部进行重写同时继续调用老的方法,在继承原数组方法时使用到

主要方法介绍:
updataView:模拟更新视图时触发的方法
observer:观察者
defineReactive:核心部分,get和set方法

//针对数组部分
let oldArrayPrototype = Array.prototype;
//继承旧数组的方法
let proto = Object.create(oldArrayPrototype)
//js省略;写法注意在括号前面加分号
;['push','shift','unshift'].forEach(method=>{
    //函数劫持
    proto[method] = function(){
        updateView()
        oldArrayPrototype[method].call(this,...arguments)
    }
})
function observer(target){
     //基本数据类型不需要处理,直接返回
    if(typeof target !== 'object' || typeof target == null){
        return target
    }
    //拦截数组,给数组重写方法
    if(Array.isArray(target)){
        // Object.setPrototypeOf(target,proto)
        target.__proto__ = proto
    }
    //循环重新定义data里面的属性和值
    for (let key in target){
        defineReactive(target,key,target[key])
    }
}
//get和set方法
function defineReactive(target,key,value){
    observer(value)//递归观察
    Object.defineProperty(target,key,{
        get(){
            //需要进行依赖收集
            return value
        },
        set(newValue){
            if(value !== newValue){
                observer(newValue)//更新后的数据也需要递归观察
                updataView();
                value = newValue
            }
        }
    })
}


//模拟更新视图
function updataView(){
    console.log("视图更新")
}
        
let data = {name:'fur',hobby:{play:"code"},age:[1,2,3]}
observer(data)
//三种写法,触发视图更新三次
data.hobby.play = {name:"js"}//视图更新
data.hobby.play.name = "ts"//视图更新
data.age = [1]//视图更新

vue2的缺陷很明显:

  • 需要响应式的数据不能是新增属性
  • 会多次嵌套递归,而且是一上来就递归,造成浪费,内存增大

建议大家看vue3,源码下载👉vue-next
vue3响应式

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值