首页 > 其他 > 详细

vue 2 简化版数据响应原理

时间:2021-04-11 15:56:16      阅读:25      评论:0      收藏:0      [点我收藏+]
// vue2对象响应式原理:Object.defineProperty()
// vue2数组响应式原理:覆盖可以修改数组7个方法
// 从数组原型中获取这7个方法,并覆盖为可以发送更新通知的函数实现
const originalProto = Array.prototype
const arrayProto = Object.create(originalProto)
;[‘push‘, ‘pop‘, ‘shift‘, ‘unshift‘, ‘splice‘, ‘reverse‘, ‘sort‘].forEach(
  method => {
    arrayProto[method] = function() {
      // 做之前的事情
      originalProto[method].apply(this, arguments)

      // 通知更新
      notifyUpdate()
    }
  }
)

// 思想:递归遍历传入obj,定义每个属性的拦截
function observe(obj) {
  if (typeof obj !== ‘object‘ || obj == null) {
    return obj
  }

  // 判断类型:如果是数组则替换它的原型
  if (Array.isArray(obj)) {
    Object.setPrototypeOf(obj, arrayProto)
  } else {
    const keys = Object.keys(obj)
    for (let index = 0; index < keys.length; index++) {
      const key = keys[index]
      // 对obj每个key执行拦截
      defineReactive(obj, key, obj[key])
    }
  }
}

// 具体定义指定的key拦截器
function defineReactive(obj, key, val) {
  // 递归遍历
  observe(val)

  // val实际上是一个闭包
  Object.defineProperty(obj, key, {
    get() {
      return val
    },
    set(newVal) {
      if (newVal !== val) {
        // val可能是对象
        observe(newVal)
        notifyUpdate()
        val = newVal
      }
    }
  })
}

function notifyUpdate() {
  console.log(‘页面更新!‘)
}

const data = { foo: ‘foo‘, bar: { a: 1 }, tua: [1, 2, 3] }
observe(data)
// 1.普通更新
// data.foo = ‘foooooooo‘
// 2.嵌套属性更新
// data.bar.a = 10
// data.dong = ‘lalala‘ // no ok
// 3.赋值是对象
// data.bar = {a:10}
// 4.数组
// data.tua.push(4)


// 问题分析:
// 1.需要响应化的数据较大,递归遍历性能不好、消耗较大
// 2.新增或删除属性无法监听
// 3.数组响应化需要额外实现
// 4.修改语法有限制

  

vue 2 简化版数据响应原理

原文:https://www.cnblogs.com/lzq035/p/14643753.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!