• vue2响应式原理


    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
    </head>
    <body>
      <script>
        // vue2对象响应式原理 Object.defineProperty()
        // vue2数组响应式原理 覆盖可以修改数组的7个方法
        // 从数组原型中获取这7个方法,并覆盖为可以发送更新通知的函数实现
        const originalProto = Array.prototype
        // 克隆数组原型,复制新的原型对象
        const arrayProto = Object.create(originalProto)
        const meArr = ['push','pop','shift','unshift','splice','reverse','sort']
        meArr.forEach(
          method => {
            // 做原型数组方法做的事情
            arrayProto[method] = function(){
              originalProto[method].apply(this,arguments)
              // 通知更新
              notifyUpdate()
            }
          } 
        )
    
        // 思想: 递归遍历传入obj,定义每个属性的拦截
        function observe(obj){
          if(typeof obj !== 'object' || obj == null){
            return
          }
    
          // 判断类型,如果是数组就替换他的原型
          if(Array.isArray(obj)){
            Object.setPrototypeOf(obj,arrayProto)
          }else{
            // 拿出对象的key值
            const keys = Object.keys(obj)
            for (let index = 0; index < keys.length; index++) {
              const key = keys[index];
              // 对obj的每个数据进行拦截
              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){
                observe(newVal)
                notifyUpdate()
                val = newVal
              }
            }
          })
        }
    
        function notifyUpdate(){
          console.log('页面更新');
        }
    
        const data = {foo:'foo',bar:{a:1},arr:[1,2,3]}
        observe(data)
        // 1普通更新
        // data.foo = 'foooooooo'
        // 2嵌套对象更新
        // data.bar.a = 10
        // 3直接赋值对象
        // data.bar = {a:10}
    
        // 数组更新
        data.arr.push(4)
    
        // vue2的问题分析
        // 1需要响应的数据较大时,递归遍历性能不好,消耗较大
        // 2新增或删除属性无法监听
        // 3数组响应化需要额外实现,导致语法有限制,如数组length无法操作数组,通过$set等方法实现
      </script>
    </body>
    </html>
  • 相关阅读:
    8086标志
    微内核
    枚举算法
    ajax
    面向对象技术概述
    ajax
    存储技术
    自然数组排列
    将搜索二叉树转换成双向链表
    在单链表中删除指定值的节点
  • 原文地址:https://www.cnblogs.com/zwhbk/p/12431464.html
Copyright © 2020-2023  润新知