Skip to content

由于Object.defineProperty无法监听数组,所以数组类型实现响应式,需要重写数组的原型方法 ​

js
     // 视图更新
  function updateView() {
   console.log("视图更新");
 }
 

//由于Object.defineProperty无法监听数组,所以数组类型实现响应式,需要重写数组的原型方法
const oldArrayProperty = Array.prototype
const arrProto = Object.create(oldArrayProperty);
["push","pop","shift","unshift","splice"].forEach(item=>(arrProto[item]=function(){
        updateView()
        oldArrayProperty[item].call(this,...arguments)
    })
)



//将传入的data属性进行深度监听,判断是对象还是数组
function observer(target){
    if(typeof target !== 'object' || target === null) return target;
    //如果是数组就重写数组原型方法
    if(Array.isArray(target)){
        target.__proto__ == arrProto
    }
    //如果是对象,遍历所有属性使用Object.defineProperty转化为getter/setter
    for(let key in target){
        defineReactive(target,key,target[key])
    }
}
    //使用Object.definePropert把属性转化为getter/setter
    function defineReactive(target,key,value){
    //多层级使用递归
    observer(value)
    Object.defineProperty(target,key,{
        get(){
            return value
        },
        set(newValue){
            observer(value)
            if(newValue !== value){
                value = newValue
                //更新视图
                updateView()
            }
        }
    })
}
// 声明要响应式的对象
const data = {
   name: "zhangsan",
   age: 20,
   info: {
     address: "北京" // 需要深度监听
   },
   nums: [10, 20, 30]
 };
 
 // 执行响应式
 observer(data);
//  修改触发响应响应式
data.name ='zhf'