• vue 2 简化版数据响应原理


    // 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()
        }
      }
    )
    
    const isObject=(obj)=>{
      return obj !== null && typeof obj === 'object'
    }
    // 思想:递归遍历传入obj,定义每个属性的拦截
    function observe(obj) {
      if (!isObject(obj)) {
        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.修改语法有限制
    

      

  • 相关阅读:
    输入框只能输入数字
    浅谈语义化【转】
    用正则过滤敏感词
    js中操作数组的一些方法【转】
    js正则表达式校验非负整数:^d+$ 或 ^[1-9]d*|0$ 【转载】
    cookie
    JSON1:使用TSQL查询和更新 JSON数据
    基于jQuery实现的Tabs选项卡自定义插件
    基于jQuery实现的Accordion手风琴自定义插件
    点击div全选中div里面的文字
  • 原文地址:https://www.cnblogs.com/lzq035/p/14643753.html
Copyright © 2020-2023  润新知