vue 响应式

(一)什么是VUE响应式

组件的data一旦变化,立即触发视图更新,是实现数据驱动视图的第一步

(二)响应式核心

API:Object.defineProperty()

(三)监听范围 -- 主要考虑的情况

肯定是要监听对象的,因为组件的 data 就是一个对象,那会有以下几种情况

(1)data 对象里面只有一层 如:

{ name: 'zfb',
  age: 23
}

(2)data 里面对象嵌套多层,需要深度监听,监听每一个对象的属性

{
      name: 'zfb',
      school: {
        name: 'Northeast Agricultural University',
        address: 'Harbin',
        major: {
          mainMajor: 'Veterinary Medicine',
          otherMajor: 'computer'
        }
      }
    }

(3)监听数组

data 中某一个属性值是一个数组的情况也很常见。push、pop、shift、unshift 等数组操作改变数组后,触发页面刷新

(四)代码

<!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>
    const arrAllMethods = Array.prototype
    const arrProto = Object.create(arrAllMethods) // Object.create 不能在数组的原型航进行更改 保留原生的
    const updateMethods = ['push', 'shift', 'unshift', 'pop', 'splice', 'sort', 'reverse']
    updateMethods.forEach(method => {
      arrProto[method] = function () {
        arrAllMethods[method].call(this, ...arguments)
        updatePage()
      }
    });
    // arrAllMethods
    // 更新页面函数
    function updatePage () {
      console.log('页面更新', data)
    }

    // 监听
    function observe (object) {
      if (typeof object !== 'object' || object === null) {
        return
      }
      // 如果是数组就不走 watchChange
      if (Array.isArray(object)) {
        object.__proto__ = arrProto // 将数组的原型重新赋值
        return
      }
      for (var key in object) { // 循环对象
        watchChange(object, key, object[key])
      }
    }

    // 具体监听每一个属性
    function watchChange (obj, key, value) {
      // 如果是数组或者对象 需要深度监听 要监听到对象的每一个属性
      if (typeof value === 'object') {
        observe(value)
        return
      }
      Object.defineProperty(obj, key, {
        get: function () {
          return value
        },
        set: function (newValue) {
          if (value !== newValue) {
            observe(newValue) // 设置新值也需要深度监听 可能字符串修改成对象
            value = newValue
            updatePage()
          }
        }
      })
    }

    let data = {
      name: 'zfb',
      school: {
        name: 'Northeast Agricultural University',
        address: 'Harbin',
        major: {
          mainMajor: 'Veterinary Medicine',
          otherMajor: 'computer'
        }
      },
      score: [100, 98, 68]
    }

    // 监听data值变化函数
    observe(data)

    data.name = 'dd'
    delete data.name // 无法监听 删除属性 this.$delete
    data.age = '23' // 新增属性 无法监听 this.$set
    data.school.name = { text: 'dd' } // 深度监听
    data.school.name.text = 22 // 可以监听
    data.school.major = {} // 无法监听 得修改到具体的根属性

    data.score.push(1)
  </script>
</body>
</html>

(五)缺点

 

(七)总结

数组:更改在原生数组原型的基础上更改Vue数组的原型 目的的为了监听数组改变 更新视图

对象:利用Object.defineProperty() 监听对象的属性变化,注意 深层对象监听(深度监听)需要循环绑定监听

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值